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,代码编译文件,即使使用-Wall -Wextra,除了对的复制构造函数的unused parameter警告。base

我认为这可能是 gcc 4.1.2 中的编译器错误,但我在网上找不到任何东西。有没有人见过这个?

我无法在没有巨大痛苦的情况下更新编译器。除了将基类的复制构造函数公开之外,还有简单的解决方法吗?


编辑base b;在第 21 行之前添加derived::foo()。在这种情况下,gcc 4.6.1 和 gcc 4.1.2 抱怨默认 ctorbase是受保护的,clang 2.9 编译时没有警告。这就是 David Rodríguez - dribeas 在他的评论中所说的 - 默认 ctor 不能在base.


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

4

2 回答 2

1

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

class derived : base {
    struct from_base_foo {};
    derived( from_base_foo ) : base( base::foo() ) {}
public;
    derived foo() {
       return derived( from_base_foo() );
    }
};
于 2012-07-13T15:05:05.680 回答
0

我的初步解决方案是制作basector 的副本public。要禁止derived使用 的复制 ctor 复制实例base,继承需要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;
    }
};
于 2012-07-16T07:28:47.170 回答