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ます。

Centos 5.8 で gcc 4.1.2 を使用してこれをコンパイルすると、次のエラーが発生します。

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 parameterbase

これは gcc 4.1.2 のコンパイラのバグである可能性があると思いますが、ネット上で何も見つけることができませんでした。誰もこれを見たことがありますか?

多大な苦痛なしにコンパイラを更新することはできません。基本クラスのコピー コンストラクターを公開する以外に簡単な回避策はありますか?


EDITbase b;の 21 行目の前に追加しましたderived::foo()。その場合、gcc 4.6.1 と gcc 4.1.2 はデフォルトの ctorbaseが保護されていると文句を言い、clang 2.9 は警告なしでコンパイルします。これは、David Rodríguez - dribeas がコメントで述べたことです - デフォルトの ctor は、 の別のインスタンスで呼び出すことはできませんbase


EDIT 2ここで適用されると思われる標準段落は 11.5 [class.protected] です。gcc 4.1.2 は私のコードを間違っているとして拒否する点で正しいようですが、なぜ gcc 4.6.1 と clang がそれを許可しているのか疑問に思います。予備的な解決策については、私自身の回答を参照してください。

4

2 に答える 2

1

試すことができる回避策には、 base 関数を呼び出して base を構築する、派生のプライベート コンストラクターを作成することが含まれます。

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

私の暫定的な解決策は、make base's copy ctorpublicです。derivedのコピー ctor を使用したインスタンスのコピーを禁止するには、継承をの代わりにbaseする必要があります。結果のクラスは次のようになります。protectedpublic

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 に答える