从抽象类派生的类的调用方法[C ++] [英] Calling methods of class derived from an abstract class [C++]

查看:162
本文介绍了从抽象类派生的类的调用方法[C ++]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果这是一个非常基本的问题,您必须原谅我;我已经很长时间没有使用C ++了,所以我忘记了它的工作原理。



无论如何,我有一个基类和几个派生类像这样的类(超级简单化了,但要旨是一样的):

  class Base 
{
public:
Base(){}
int SomeFunction(int x,int y); //抽象定义
};

类Derived1:公共Base
{
public:
Derived1():Base(){}
int SomeFunction(int x,int y)
{
//实际执行
返回4;
}
};

类Derived2:公共Base
{
public:
Derived2():Base(){}
int SomeFunction(int x,int y)
{
//实际执行
返回7;
}
};

以后在 main 中有一个列表 Base 个对象:

  Base * baseobjects [10]; 

后来我用 Derived1 和 Derived2 。这适用于 baseobjects [i] =& newDerived1 (其中 newDerived1 Derived1 类)。没关系。



我似乎无法弄清楚如何稍后遍历 baseobjects 数组并在列表中的每个实例上调用 SomeFunction ,而无需明确知道我正在使用哪个派生类。我已经在C#中完成了它,并且工作正常,但显然我的C ++语法已关闭:

  int result = baseobjects [i ]-> SomeFunction(a,b); 

这给我一个 LNK2019 错误尝试编译,显然是因为它在寻找实现的 Base 类,但它不存在。我假设我必须使用一些指针技巧才能使它查看正确的派生方法,但我尝试过的任何方法都没有奏效。

解决方案

您的方法应声明为 virtual 。在您的情况下,可能 虚拟

  class Base 
{
public:
Base(){}
virtual int SomeFunction(int x,int y)= 0; //抽象定义
};

请注意,虽然这不是绝对必需的,但您最好声明虚拟析构函数。如果您曾经通过基类的指针删除派生实例,则执行此操作。

  class Base 
{
public:
// Base(){} //这不是必需的,提供的默认构造函数类似。
virtual〜Base(){} //虚拟析构函数。
virtual int SomeFunction(int x,int y)= 0; //抽象定义
};



编辑:



另外,关于您发布的链接错误:



您忘记了 = 0 ,或者您正在调用 Base :: SomeFunction()



正如 Thomas Edleson 指出的那样, = 0 并不意味着您的函数没有实现:它可以有一个实现,但是它只需要派生类来(重新)实现它就不会抽象。 / p>

如果您对此主题感兴趣,建议您阅读此帖子


You'll have to forgive me if this is a really basic question; I haven't used C++ this much in a long time so I've forgotten how a lot of it works.

Anyway, I have a base class and a couple derived classes like this (super oversimplified, but the gist is the same):

class Base
{
public:
   Base () { }
   int SomeFunction (int x, int y); // abstract definition
};

class Derived1 : public Base
{
public:
   Derived1() : Base() { }
   int SomeFunction (int x, int y)
   {
      // actual implementation
      return 4;
   }
};

class Derived2 : public Base
{
public:
   Derived2() : Base() { }
   int SomeFunction (int x, int y)
   {
      // actual implementation
      return 7;
   }
};

Later on in main I have a list of Base objects:

Base *baseobjects[10];

Later I fill that array with instances of Derived1 and Derived2. That works with baseobjects[i] = &newDerived1 (where newDerived1 is an instance of the Derived1 class). That's all fine.

What I can't seem to figure out is how to later iterate through the baseobjects array and call SomeFunction on every instance in the list without explicitly knowing which derived class I'm using. I've done this in C# and it works fine, but apparently my C++ syntax is off:

int result = baseobjects[i]->SomeFunction(a, b);

That gives me a LNK2019 error when I try to compile, apparently because it's looking at the Base class for the implementation and it isn't there. I'm assuming I have to use some pointer tricks to get it to look at the proper derived method, but nothing I've tried yet has worked. Any suggestions?

解决方案

Your method should be declared virtual. And in your case, probably pure virtual.

class Base
{
public:
   Base () { }
   virtual int SomeFunction (int x, int y) = 0; // abstract definition
};

Note that, while this is not absolutely required, you might as well declare a virtual destructor. Do it if you ever delete a derived instance trough a pointer of the base class.

class Base
{
public:
   //Base () {} // This is not required, the default provided constructor is similar.
   virtual ~Base() {} // virtual destructor.
   virtual int SomeFunction (int x, int y) = 0; // abstract definition
};

Edit:

Also, regarding the link error you posted:

Either you forgot the = 0, either you are calling Base::SomeFunction() from somewhere.

As Thomas Edleson points out, = 0 does not mean that your function has no implementation: it can have one, but it only requires the derived classes to (re)implement it to not being abstract.

If you are interested in this topic, I suggest you read this post.

这篇关于从抽象类派生的类的调用方法[C ++]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆