简体   繁体   English

C ++基类函数调用从钻石设计的最后派生

[英]C++ base class function call from last derived in diamond design

I'm learning C++ and after having read and tested a lot about multiple inheritance, virtual inheritance/methods and diamond design I still have some problems to understand it till the end. 我正在学习C ++,在阅读和测试了很多有关多重继承,虚拟继承/方法和钻石设计的知识之后,直到最后我仍然有一些问题需要理解。

I'm in the diamond design pattern, where class B e C inherit virtual public A and D inherits public B, public C : 我处于菱形设计模式中,其中类B e C继承virtual public A而类D继承public B, public C

    A
  /   \
 B     C
  \   /
    D

All classes implement a private variable std::string _message that I initialize with the following string. 所有类都实现了一个私有变量std::string _message ,我使用以下字符串对其进行了初始化。

 "class-name instance"

Only Class A implements a virtual public display(void) const method too. Class A实现了一个virtual public display(void) const方法。

void     display(void) const{
     std::cout << this->_message << std::endl;
}

The main is: 主要是:

D foo;
foo.display();

The output is: 输出为:

A instance

However when I "inspect" the element debugging step by step with Xcode I see that inside the D instance I can correctly find a B, a C and A object (just one shared by B and C) with all the different _message correctly assigned. 但是,当我使用Xcode逐步“检查”元素调试时,我发现在D实例内部,我可以正确找到一个B,一个C和A对象(B和C共享一个对象),并正确分配了所有不同的_message

What I'm doing wrong? 我做错了什么? Need I override the display() method in D class? 我需要重写D类中的display()方法吗? But if so, which is the real point of multiple inheritance if I have to re-implements the same method in a derived class? 但是,如果是这样,如果我必须在派生类中重新实现相同的方法,那么多重继承的真正意义是什么?

Your question seems to not be related to the diamond pattern, but is generally about the inheritance model in C++. 您的问题似乎与菱形图案无关,但通常与C ++中的继承模型有关。 Most things in C++ are statically bound, so at compile time the compiler fixes what method or member of a certain name is used: C ++中的大多数东西都是静态绑定的,因此在编译时,编译器会修复使用哪种方法或某个名称的成员:

If you access a member of the implicit this object or using a pointer or reference to an object, you will end up accessing a member of the class the pointer or reference has at compile time, no matter whether at runtime there is a derived-class object that has members of the same name. 如果访问隐式this对象的成员,或者使用指针或对对象的引用,那么无论在运行时是否存在派生类,最终都将在编译时访问指针或引用所具有的类的成员具有相同名称成员的对象。 That's why they say you can not override but just shadow members in base classes when you define an equal named member in the derived class. 这就是为什么他们说,当您在派生类中定义一个相等的命名成员时,您不能覆盖而只能覆盖基类中的影子成员。

The same thing is true for non-virtual functions. 非虚拟功能也是如此。

The only thing that behaves different is virtual functions. 唯一表现不同的是虚函数。 These functions can be overwritten in derived classes, and code that gets handed a pointer-to-base-class can virtual functions of the base class and end up executing implementations given in the derived class. 可以在派生类中覆盖这些函数,并且将指针传递给基类的代码可以虚化基类的功能,并最终执行派生类中给定的实现。

So the point of virtual functions is not to have the compiler reinterpret a certain function in the context of derived classes (as you seem to understand it), but to make it possible to replace a function in the base class by a different function in the derived class. 因此,虚函数的意义不在于让编译器在派生类的上下文中重新解释某个函数(如您所理解的那样),而是可以用一个不同的函数替换基类中的函数。派生类。

To go back to your motivation: If you want a display function that prints a message that depends on the actual object type, the thing that is fixed is the printig, which doesn't need to be virtual. 回到您的动机:如果您想要一个display功能来打印一条消息,该消息取决于实际的对象类型,则固定的是printig,它不需要是虚拟的。 But you need a virtual function to obtain the object type. 但是您需要一个虚拟函数来获取对象类型。 Like this: 像这样:

#include <iostream>
#include <ostream>

class A {
public:
    void display() { std::cout << get_message() << '\n'; }
    virtual const char * get_message() { return "A instance"; }
};

class B : virtual public A {
public:
    virtual const char * get_message() { return "B instance"; }
};

class C : virtual public A {
public:
    virtual const char * get_message() { return "C instance"; }
};

class D : public B, public C {
public:
    // virtual const char * get_message() { return B::get_message(); }
    // virtual const char * get_message() { return C::get_message(); }
    // virtual const char * get_message() { return "D instance"; }
};

int main(void)
{
    D foo;
    foo.display();
    A* a_ptr = &foo;
    a_ptr->display();
    return 0;
}

The example as given will not compile (now this is due to the diamond pattern), because the compiler can not decide, what overrider of A::get_message() , either B::get_message() or C::get_message() should be picked in D objects, you need to make one of the comments in D real code to declare the one-and-only get_message for D, in which can re-use the existing functions. 给出的示例将无法编译(现在这是由于菱形图案引起的),因为编译器无法确定A::get_message()替代方法, B::get_message()还是C::get_message()在D对象中被选中后,您需要在D实代码中进行注释之一,以声明D的唯一get_message ,在其中可以重用现有功能。

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

相关问题 C ++要从基类调用派生函数 - C++ want to call derived function from base class C ++从基类实例调用派生函数 - C++ Call derived function from base class instance C ++如何从main调用派生的基类函数 - C++ How to call a derived base class function from main 如何调用所有基类的复制构造函数来复制C ++中钻石继承中的大多数派生类对象? - How to call copy constructor of all base classes for copying most derived class object in diamond inheritance in C++? 从基对象上的 C++ 类调用重载的派生函数不会调用重载函数 - Call overloaded, derived function from C++ class on base object does not call the overloaded function 是否可以从C ++的派生类中调用基类中的方法? - is it possible to call a method in the base class from a derived class in c++? C ++如何从基类调用派生类中的方法 - C++ how to call method in derived class from base class C ++通过指向基类的派生类中的指向成员函数调用 - C++ call via pointer-to-member function in a derived class from the base class C ++从基类派生的类中调用函数,而无需强制转换且没有虚拟方法 - C++ Call a function in a derived class from base class without casting and no virtual methods C ++没有匹配函数可以从派生类调用基类方法 - c++ no matching function for call to base-class method from derived-class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM