C++ 使用抽象类初始化并创建实现此抽象类的对象

C++ 使用抽象类初始化并创建实现此抽象类的对象,c++,c++11,C++,C++11,我将首先发布我目前拥有的代码。我尽量减少它,但由于我没有经验丰富的C++,我不知道我可能已经离开了很多或只是显示了很多代码。 class IBehavior { public: virtual void DoIt() = 0; }; class BehaviorA : public IBehavior { void DoIt() { cout << "Behavior: A\n"; }; }; class BaseOfAB { IBehavior be

我将首先发布我目前拥有的代码。我尽量减少它,但由于我没有经验丰富的C++,我不知道我可能已经离开了很多或只是显示了很多代码。
class IBehavior {
public:
  virtual void DoIt() = 0;
};

class BehaviorA : public IBehavior {
  void DoIt() {
      cout << "Behavior: A\n";
  };
};

class BaseOfAB {
  IBehavior behavior;

  void DoIt() {
      behavior.DoIt();
  };
};

class A : public BaseOfAB {
  A() {
    BehaviorA behavior;   
  };  
};

int main()
{
    A objA;
    objA.DoIt();

    return 0;
}
类IBehavior{
公众:
虚空DoIt()=0;
};
类行为:公共IBehavior{
void DoIt(){

Cuth

为实现C++中的多态性,需要一个指针或引用基类。因为<代码> BasoBAB <代码>将拥有这个多态对象,您不能使用引用,但必须使用指针。最好是智能指针,这样您就不用担心手动内存管理。接口<代码> IBehavior <代码>将不得不有一个虚拟析构函数,因此如果删除指向

IBehavior
的指针,它将正确删除派生类

<>我选择了 STD::UnQuyGPPT/<代码>,因为它是C++中最轻量级的智能指针,尽管您需要了解C++移动语义来处理它。
#include <iostream>
#include <memory>

class IBehavior {
public:
  virtual void DoIt() = 0;
  virtual ~IBehavior() = default;
};

class BehaviorA : public IBehavior {
public:
  void DoIt() override { std::cout << "Behavior: A\n"; }
};

class BaseOfAB {
  std::unique_ptr<IBehavior> behavior;
public:
  BaseOfAB(std::unique_ptr<IBehavior> behavior) : behavior(std::move(behavior)) {}
  void SetBehavior(std::unique_ptr<IBehavior> newBehavior) {
    behavior = std::move(newBehavior);
  }
  void DoIt() { behavior->DoIt(); };
};

class A : public BaseOfAB {
public:
  A() : BaseOfAB(std::make_unique<BehaviorA>()) {}  
};

int main() {
    A obj;
    obj.DoIt();
    obj.SetBehavior(std::make_unique<BehaviorB>());
    obj.DoIt();
}
#包括
#包括
IBehavior类{
公众:
虚空DoIt()=0;
virtual~IBehavior()=默认值;
};
类行为:公共IBehavior{
公众:
void DoIt()重写{std::cout DoIt();};
};
A类:公共基地{
公众:
A():BaseOfAB(std::make_unique()){
};
int main(){
obj;
obj.DoIt();
对象设置行为(std::make_unique());
obj.DoIt();
}


使用智能指针
std::unique_ptr
可确保在删除
BaseOfAB
实例或在
SetBehavior
中替换它时正确删除
IBehavior
实例。它还为复制/移动构造函数和复制/移动分配提供合理的默认行为。

对于多形性要工作,您需要一个指向具体对象的指针或引用(通过基类表示,例如,
IBehavior*
)。并且您需要重写实际的纯虚函数,而不是其他一些无关的函数。请阅读相关内容(无论如何,您都需要阅读,因为您在类、继承和成员方面犯了一些非常基本的错误)。我不理解这个问题,但这段代码不起作用,因为您试图创建抽象类的对象(
BaseOfAB::behavior
)@Someprogrammerdude:你能解释一下我在这种情况下做错了什么吗?我会看一些好书。你说的重写实际的纯虚拟函数是什么意思?这不是我在做的吗?对不起,这是真的,现在就去编辑它。你需要能够在运行时更改子类的行为还是在编译时修复它?如中所述,
A
是否始终使用
BehaviorA
?感谢您的帮助。非常感谢。您能给我解释一下这些智能指针是怎么回事吗?我在一门课程中确实了解到了一些,但没有详细介绍。如果我没有记错的话,虚拟析构函数将确保在删除时尝试使用mpt是否将其作为派生对象而不是基类删除?@SSJVegetto我添加了一些解释,但我认为对智能指针的深入解释超出了这个答案的范围,我建议您使用。@SSJVegetto是的,您对虚拟析构函数的看法是正确的。如果对
std::unique的使用有任何具体的说明,请参阅_ptr
您不懂,请随意提问。