具有智能指针的多态性
Polymorphism with smart pointer
正如答案所指出的,这是我犯的一个愚蠢的错误,与多态性或智能指针无关。更正后的版本在接受的答案中。
====
================================我正在尝试使智能指针与多态性一起工作。在下面的原型代码中,纯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;
你那里有一些错别字,应该是:
int main()
{
DerivedWrap pDW1; // object instantiation, no () needed
pDW1.print(); //no dereferencing required
DerivedWrap pDW2(make_unique<Derived>(2));
pDW2.print(); // again, no dereference required
return 0;
}
另一个注意事项是,对于多态对象,您将需要在基类中使用虚拟析构函数。
这与多态性、虚函数或智能指针无关。
你刚刚犯了两个小的印刷错误:
DerivedWrap pDW1();
声明一个函数。删除()
。->
取消引用指针,但pDW1
和pDW2
都不是函数。请改用.
。
相关文章:
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 具有智能指针的多态性
- 如何使用静态多态性在 int 和指针类型之间进行转换?
- 无法初始化已知大小的矢量指针,该大小不会因多态性而更改
- 如何调用指针类型的方法(禁用多态性)?
- 创建基类指针的向量并将派生类对象传递给它(多态性)
- 如何避免指针超出范围(多态性)的C++分段错误
- C++ 被此代码与多态性、指针和对象切片混淆
- 在同时处理基类的多个指针时如何处理多态性?
- 如果基类指针无法访问派生类成员函数,那么多态性有什么方便的呢?
- 与智能指针和矢量C 的多态性有关的问题
- C - 删除多态性指针
- 载体包含指向多态性类别的指针
- 集合中的智能指针多态性
- 多态性和STL容器.指针是不必要的
- 由支持多态性的值池存储,如何使用智能指针
- 如果我需要多态性,我应该使用原始指针而不是unique_ptr
- 没有指针的多态性
- 如何在使用动态多态性时避免指针
- 方法重写(没有虚拟方法或指针)是否被认为是多态性的一部分