简体   繁体   English

函数在派生类中但不在基类中,指向基类的指针-->“不是成员”错误

[英]function in derived but not in base class, pointer to base --> "not a member" error

As the title states, I have a base class (interface) and several derived classes.正如标题所述,我有一个基类(接口)和几个派生类。 On the derived classes, I have some extra functions that don't make sense to implement on the interface class - neither on all derived classes.在派生类上,我有一些额外的功能在接口类上实现没有意义——在所有派生类上都没有。

In my program, I have a vector of pointers to base classes - but the actual objects are all of derived classes.在我的程序中,我有一个指向基类的指针向量——但实际对象都是派生类。

Now, if I try to call a function of a derived class, I get a compiler error.现在,如果我尝试调用派生类的函数,则会出现编译器错误。 Even if I know for sure the derived type that a particular object will have, I cannot call the function.即使我确定知道特定对象的派生类型,我也无法调用该函数。

How do I get around this?我该如何解决这个问题? Would this point to a design problem?这会指向设计问题吗? Should I convert the pointer/create a new pointer of that specific type?我应该转换指针/创建该特定类型的新指针吗?

The last option seems to work, but makes the code very ugly with tons of if-else blocks.最后一个选项似乎可行,但使用大量if-else块会使代码非常难看。

Here is some example code to reproduce the error:以下是重现错误的一些示例代码:

#include <iostream>

class Base {
public:
    Base() {};
    ~Base() = default;
};
    
class Derived: public Base {
public:
    Derived() {};
    ~Derived() = default;
    void foo() {
        std::cout << "foo()" << std::endl;
    }
};
    
int main()
{
    Base* ptr = new Derived();
    *ptr->foo();
    delete ptr;
}

EDIT: I do know about virtual functions, but this is not what I'm looking for.编辑:我知道虚函数,但这不是我要找的。 My point is that it would make no sense to implement foo() on the base class nor on all of the derived classes.我的观点是,在基类或所有派生类上实现 foo() 是没有意义的。 foo() is something very specific to one specific derived class. foo() 是特定于一个特定派生类的东西。 Example: my base class is Vehicle, my derived classes are Car, Helicopter, Speedboat.示例:我的基类是 Vehicle,我的派生类是 Car、Helicopter、Speedboat。 My function is checkTirepressure() - as you see this function doesn't make any sense on Helicopter or Speedboat.我的功能是 checkTirepressure() - 如您所见,此功能在直升机或快艇上没有任何意义。

To run the function of derived class from the base class pointer, make sure that the function you want to run have same name and return type function in base class and in addition make sure that the function in base class has virtual keyword before to its return type.要从基类指针运行派生类的函数,请确保要运行的函数在基类中具有相同的名称和返回类型函数,此外还要确保基类中的函数在返回之前具有virtual关键字类型。 Let me explain with an example....让我用一个例子来解释......

#include<iostream>
using namespace std;

class base{
public:
virtual void func(){
    cout<<"hello";
 }
};

 class derived: public base
{
 public:
 void func(){
     cout<<"Hi";
 }
 };

  int main(){
  base* b1=new derived;
  b1->func();
  return 0;
  }

here the base class pointer is pointing to function of derived class...这里基类指针指向派生类的函数......

Understand that thing the function you want to run should have same name and return type in both of the classes but in addition there is the virtual key word before this function in the base class.了解您要运行的函数在两个类中应具有相同的名称和返回类型,但此外在基类中此函数之前还有虚拟关键字。

Yes there is a way around it, by something what is called "down casting" but you do not want to go there, as you already mentioned in your question - would it be a design problem?是的,有一种解决方法,通过所谓的“向下铸造”,但你不想去那里,正如你在问题中已经提到的那样 - 这会是一个设计问题吗? Yes, it would.是的,会的。

Instead you need to understand the basic differences between compile time polymorphism and runtime polymorphism.相反,您需要了解编译时多态性和运行时多态性之间的基本区别。 You in your given sample are trying to achieve runtime polymorphism.您在给定示例中正在尝试实现运行时多态性。

Try to think of it this way:试着这样想:

When you are creating an interface (base class), you are creating something that demonstrates what functionalities are available.当您创建一个接口(基类)时,您正在创建一些东西来演示可用的功能。 In a train it would be the main controls that allow you to operate the train.在火车中,它是允许您操作火车的主要控制装置。

The implementation (derived class) of that interface is hidden from you (you don't see how the red button starts up the engine).该接口的实现(派生类)对您是隐藏的(您看不到红色按钮如何启动引擎)。

In programming it is the same.在编程中也是如此。 In your interface (base class) you need to define what will be available to you, but you don't have to implement it.在您的接口(基类)中,您需要定义您可以使用的内容,但您不必实现它。 To do this you need the virtual keyword to define a (pure) virtual function, which you define later.为此,您需要使用 virtual 关键字来定义一个(纯)虚函数,您稍后会定义它。 I won't go into detail how virtual functions work (you can read about that yourself).我不会详细介绍虚函数的工作原理(您可以自己阅读)。 Ie: IE:

#include <iostream>
class Base {
public:
    Base() {};
    ~Base() = default;
    //foo() is virtual and can have it's own implementation
    //you can still override this function in the derived class
    virtual void foo() {std::cout << "foo";}; // virtual function
    //pure virtual functions are without an implementation and must be
    //implemented in their derived classes
    virtual void bar() = 0; //pure virtual 
};

Now in your sample what you are doing (without virtual functions) is the following:现在在你的例子中你正在做什么(没有虚函数)如下:

int main()
{
  //You are creating a pointer to Base class, your compiler knows
  //this during compile time. During runtime you are allocating
  //a Derived class and pointing to it with the Base ptr
  Base* ptr = new Derived(); 
  //During compile time it doesn't know that you are supposed to
  //be able to call this function, because it still sees it as a 
  //Base class. If this would pass the compilation it would have 
  //a problem during runtime as well! It wouldn't be able to find
  //the function, because you didn't tell the program that Base 
  //class is supposed to in the case of polymorphism
  //expect such a function (it did not create a hidden pointer in
  //it's vtable that could potentially store the function pointer)  
  *ptr->foo();
  delete ptr;
}

I recommend reading about:我建议阅读:

  1. Virtual method table虚方法表
  2. Polymorphism多态性

Hope it helps!希望能帮助到你!

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

相关问题 “指向成员的派生指针”到“指向成员的基指针”错误 - "Derived pointer to member" to "base pointer to member" error 使用基类函数指针访问派生类成员函数 - Using base class function pointer to access derived class member function 如何注册派生的 class 成员 function 指针与基数 class - How to register a derived class member function pointer with a base class 在派生类的对象上使用指向基类的成员函数的指针 - Using pointer to member function of a base class on object of derived class 成员函数指针转换,从派生类到基类 - Member function pointer cast, from Derived to Base class 如何通过派生的指针在基类中调用模板成员函数 - How to call template member function in the base class by the derived pointer 指向派生 class 中的基 class 作为成员变量的指针 - Pointer to base class in derived class as a member variable 尝试通过基类指针访问派生类成员函数将导致哪种错误? - What kind of error will result from attempting to access a derived class member function through a base class pointer? 具有派生成员的基类的唯一指针 - unique pointer of base class with derived member 无法将“指向派生类的成员指针”转换为“指向基类的成员指针” - Cannot cast “member pointer to derived class” to “member pointer to base class”
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM