正如答案所指出的,这是我犯的一个愚蠢的错误,与多态性或智能指针无关。更正后的版本在接受的答案中。
============== 原始问题 ==================
我正在尝试使智能指针与多态一起工作。在下面的原型(prototype)代码中,纯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
析构函数,用于定义的行为。查看更多:When to use virtual destructors?
简而言之,你需要
#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();
}
作为旁注,请do not practice with
using namespace std;
关于c++ - 智能指针的多态性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/62457465/