答えが指摘しているように、これは私が犯したばかげた間違いであり、ポリモーフィズムやスマートポインターとは何の関係もありません。修正されたバージョンは、受け入れられた回答にあります。
==============元の質問==================
私はスマートポインターをポリモーフィズムで機能させようとしています。次のプロトタイプコードでは、純粋virtual
関数の実装Base::print()
はDerived
オブジェクトのメモリブロックにある必要があります。オブジェクトDerivedWrap
へのポインタにアクセスできDerived
ます。
DerivedWrap::print()
関数の実装にアクセスできないのはなぜですか?
using namespace std;
class Base
{
public:
virtual void print() = 0;
};
class Derived : public Base
{
public:
Derived(int in) : i(in) {}
void print() {
cout << "int is " << i << endl;
}
private:
int i;
};
class DerivedWrap
{
public:
DerivedWrap() : DerivedWrap(make_unique<Derived>(2)) {}
DerivedWrap(unique_ptr<Base> pBase) : _pBase(move(pBase)) {}
void print()
{
_pBase->print();
}
private:
unique_ptr<Base> _pBase;
};
int main()
{
DerivedWrap pDW1();
pDW1->print(); // error: request for member ‘print’ in ‘pDW1’, which is of non-class type ‘DerivedWrap()’
DerivedWrap pDW2(make_unique<Derived>(2));
pDW2->print(); // error: base operand of ‘->’ has non-pointer type ‘DerivedWrap’
return 0;
}
いくつか問題があります。
DerivedWrap pDW1();
は、戻り値の型がDerivedWrap
。である関数宣言です。それはあなたが期待しているデフォルトのコンストラクターを呼び出していません。あなたは単に必要ですDerivedWrap pDW1; // calls the default constructor
// or
// DerivedWrap pDW1{};
pDW1
は単なるDerivedWrap
オブジェクトです。したがって、を呼び出す必要はありませんoperator->
。要するに必要ですDerivedWrap pDW1;
pDW1.print();
同じことがpDW2
。にも当てはまります。あなたが必要DerivedWrap pDW2(std::make_unique<Derived>(2));
pDW2.print();
Base
必須のvirtual
デストラクタです。詳細:仮想デストラクタを使用する場合要するに、あなたは必要です
#include <iostream>
#include <memory>
class Base
{
public:
virtual void print() = 0;
virtual ~Base() = default; // provide virtual destructor
};
class Derived /*final*/: public Base
{
public:
// ... other code
void print() override // recommended to override the virtual functions
{
std::cout << "int is " << i << std::endl;
}
private:
int i;
};
class DerivedWrap /* final */
{
public:
// ...other code
void print()
{
_pBase->print();
}
private:
std::unique_ptr<Base> _pBase;
};
int main()
{
DerivedWrap pDW1; // or DerivedWrap pDW1{};
pDW1.print();
DerivedWrap pDW2{ std::make_unique<Derived>(2) };
pDW2.print();
}
ちなみに、練習しないでくださいusing namespace std;
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加