首页 文章

基类复制构造函数的可见性问题

提问于
浏览
6

我有一个类(暂时叫它 base ),它有一个受保护的接口,包括受保护的构造函数等. base 的某些函数按值返回 base 的实例:

class base {
protected:
    base() {}
    base (base const &other) {}  // line 6
    base foo () {
        base ret;
        return ret;
    }
};

这些函数包装在派生类中,以返回派生类型,如下所示:

class derived : public base {
private:
    derived(base const &b) : base(b) {}
public:
    derived() : base() {}
    derived foo() {
        derived d(base::foo());  // line 21
        return d;
    }
};

为了便于从 base 返回类型转换为 derived 返回类型,我在 derived 中提供了一个处理此问题的私有构造函数 .

使用gcc 4.1.2在Centos 5.8上进行编译会产生以下错误:

test.cpp: In member function ‘derived derived::foo()’:
test.cpp:6: error: ‘base::base(const base&)’ is protected
test.cpp:21: error: within this context

使用Linux Mint 12上的gcc 4.6.1和clang 2.9,除了 base 的复制构造函数的 unused parameter 警告之外,代码编译文件,即使是 -Wall -Wextra .

我认为这可能是gcc 4.1.2中的编译器错误,但我无法在网上找到任何内容 . 谁看过这个吗?

没有大的痛苦,我无法更新编译器 . 除了使基类的复制构造函数公开之外,还有一个简单的解决方法吗?


EDIT 我在 derived::foo() 第21行之前添加了 base b; . 在这种情况下,gcc 4.6.1和gcc 4.1.2抱怨 base 的默认ctor受到保护,clang 2.9编译时没有警告 . 这就是DavidRodríguez - dribeas在他的评论中所说的 - 默认的ctor不能在 base 的不同实例上调用 .


EDIT 2 这里似乎适用的标准段落是11.5 [class.protected] . gcc 4.1.2似乎是正确的拒绝我的代码不正确,我想知道为什么gcc 4.6.1和clang允许它 . 请参阅我自己的答案以获得初步解决方案

2 回答

  • 1

    您可以尝试的解决方法包括为派生创建一个私有构造函数,通过调用基函数构造它的基础:

    class derived : base {
        struct from_base_foo {};
        derived( from_base_foo ) : base( base::foo() ) {}
    public;
        derived foo() {
           return derived( from_base_foo() );
        }
    };
    
  • 0

    我的初步解决方案是制作 base 的复制文件 public . 要禁止使用 base 的副本ctor复制 derived 实例,继承需要是 protected 而不是 public . 生成的类现在看起来像这样:

    class base {
    protected:
        base() {}
    public:
        base (base const &other) {}
    protected:
        base foo () {
            base ret;
            return ret;
        }
    };
    
    class derived : protected base {
    private:
        derived(base const &b) : base(b) {}
    public:
        derived() : base() {}
        derived foo() {
            derived d(base::foo());
            return d;
        }
    };
    

相关问题