简体   繁体   English

基类中派生类的组成

[英]composition of a derived class in a base class

for example. 例如。 We have class A and its derived class; 我们有class A类及其派生类。 class B . class B Is it possible to instantiate a pointer of type B in class A ? 是否可以实例化class A的类型B的指针?

#ifndef WARRIOR_H
#define WARRIOR_H

#include "CharacterPlayer.h"
class Warrior: public CharacterPlayer
{
public:
    virtual void printCharacterName();
};
#endif

however, when i try to instantiate a Warrior pointer or try to include "Warrior.h", it gives me a number of syntax errors. 但是,当我尝试实例化Warrior指针或尝试包含“ Warrior.h”时,它给了我很多语法错误。

#ifndef CHARACTERPLAYER_H
    #define CHARACTERPLAYER_H
    #include "Warrior.h"
    class CharacterPlayer
    {
    public:
        Warrior *warriorPntr = nullptr;
        virtual void printCharacterName();

    };
    #endif

You have a circular dependency among your headers: "CharacterPlayer.h" includes "Warrior.h" , and "Warrior.h" includes "CharacterPlayer.h" . 您的标头之间具有循环依赖关系: "CharacterPlayer.h"包括"Warrior.h""Warrior.h"包括"CharacterPlayer.h" This cannot compile, because the "sentinel" will stop inclusion. 这不能编译,因为“前哨”将停止包含。

The trick is to forward-declare the Warrior class in the CharacterPlayer instead of including a header: 诀窍是在CharacterPlayer向前声明Warrior类,而不是包含标头:

#ifndef CHARACTERPLAYER_H
#define CHARACTERPLAYER_H
class Warrior; // <<== Here
class CharacterPlayer
{
public:
    Warrior *warriorPntr = nullptr;
    virtual void printCharacterName();

};
#endif

This is good enough to declare pointers and references to Warrior , but not enough to call methods or instantiate the class. 这足以声明对Warrior指针和引用,但不足以调用方法或实例化该类。

You need to eventually include the header for Warrior in the cpp file CharacterPlayer.cpp , but that would not lead to any issues, because there is no circular dependency among your headers. 您最终需要在cpp文件CharacterPlayer.cpp包含Warrior的标头,但这不会导致任何问题,因为标头之间没有循环依赖关系。

You can, but it's not a good idea. 您可以,但这不是一个好主意。

To do it, simply remove the "#include "Warrior.h" from your second header, and replace it with a declaration of the form "class Warrior;" 为此,只需从第二个标头中删除"#include "Warrior.h" ,然后将其替换为形式为"class Warrior;"的声明即可"class Warrior;"

As to why it is a bad idea: making a base class contain a pointer to (or an instance of) a derived class is one way (of several) that ensures implementation of the base class depends on implementation of the derived class. 关于为什么这是一个坏主意:使基类包含指向派生类(或实例)的指针是确保基类实现取决于派生类的实现的一种方法。 Generally speaking, the definition of derived class should depend on the base class, not the reverse, in order to avoid circular dependencies, to allow the base class to be used polymorphically (look up "Liskov Substitution Principle), etc etc. 一般来说,派生类的定义应取决于基类,而不是相反的类,以避免循环依赖关系,以允许基类被多态使用(查找“ Liskov替代原理”等)。

This means, although it can be done, your design is fundamentally flawed. 这意味着,尽管可以做到,但是您的设计从根本上来说是有缺陷的。 It would prevent you doing other useful things in future. 它将阻止您将来做其他有用的事情。

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

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