简体   繁体   English

C++ 对动态创建的类成员函数的未定义引用

[英]C++ Undefined Reference to Function of Dynamically Created Class Member

I have four different C++ classes;我有四个不同的 C++ 类; Comp() , which contains Parent() , which has two children ChildA() and ChildB() . Comp() ,其中包含Parent() ,它有两个孩子ChildA()ChildB() I want to dynamically create an instance of ChildA or ChildB inside of Comp() depending on some parameter.我想动态创建的实例ChildAChildBComp()取决于一些参数。

My code looks a bit like this:我的代码看起来有点像这样:

class Parent {
  public:
    foo();
};

class ChildA : public Parent {
  public:
    foo(); // Overrides Parent.foo()
};

class ChildB : public Parent {
  public:
    foo(); // Overrides Parent.foo()
};

class Comp {
  public:
    Init(uint8_t someParam){
      if(someParam){
        obj = new ChildA();
      }
      else{
        obj = new ChildB();
      }
    }

    doFoo(){
        obj->foo();
    }
 
  private:
    Parent* obj;
};

However, this does not compile.但是,这不会编译。 It's throwing me linker errors saying that I have an undefined reference to Parent::foo()它向我抛出链接器错误,说我对Parent::foo()有一个未定义的引用

/build/libComp.a(Comp.cpp.o): In function `Comp::doFoo()':
Comp.cpp:(.text._ZN6Memory8readByteEt+0x4e): undefined reference to `Parent::foo()'

I feel like I'm missing something fundamental here.我觉得我在这里错过了一些基本的东西。 I'm coming from a background in Python programming so I haven't quite switched my thought process over to C++ yet.我来自 Python 编程的背景,所以我还没有完全将我的思维过程切换到 C++。 Am I allowed to use classes this way?我可以这样使用课程吗?

As you are a Python programmer you got used to the world where every method is a virtual one, and the overload means that you just replace the value in the dict.作为一名 Python 程序员,您已经习惯了每个方法都是虚拟方法的世界,而重载意味着您​​只需替换字典中的值。 C++ is somewhat different. C++ 有点不同。

So the first solution is to define the Parent::foo method.所以第一个解决方案是定义Parent::foo方法。 You have declared it, the class is not a template - so you have to define the body somewhere.您已经声明了它,该类不是模板 - 因此您必须在某处定义主体。 Anyway that wouldn't help you as calling obj->foo();无论如何,这不会帮助你调用obj->foo(); means calling the Parent::foo() method, and I guess that is not what you want.意味着调用Parent::foo()方法,我想这不是你想要的。

Now we are moving to the world of virtual methods: in C++ you have to declare a method as virtual explicitly:现在我们正在转向虚方法的世界:在 C++ 中,您必须明确地将方法声明为virtual方法:

class Parent {
  public:
    virtual foo();
};

You still need to define the body of Parent::foo() somewhere.您仍然需要在某处定义Parent::foo()的主体。

If you don't want to define it by design, you may make this method abstract (thus the class Parent becomes abstract as well, and no instance of this class can be created):如果你不想按设计定义它,你可以使这个方法抽象(因此类Parent变成抽象的,并且不能创建这个类的实例):

class Parent {
  public:
    virtual foo() = 0;
};

You don't need to declare the method foo of the derived classes as virtual (they will be anyway), but the best practice is to add either a override or final specifier:您不需要将派生类的方法foo声明为虚拟的(无论如何它们都是),但最佳实践是添加overridefinal说明符:

class ChildA : public Parent {
  public:
    foo() final; // Overrides Parent.foo()
};

class ChildB : public Parent {
  public:
    foo() override; // Overrides Parent.foo()
};

The difference is that you cannot override this method for ClassA and you can do this for the ClassB .不同之处在于您不能为ClassA重写此方法,而可以为ClassB重写此方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM