调用从抽象类派生的类的方法 [C++]

发布于 2024-10-18 02:54:57 字数 1238 浏览 3 评论 0原文

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

无论如何,我有一个基类和几个像这样的派生类(超级过于简单,但要点是相同的):

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;
   }
};

稍后在 main 中,我有一个 Base 列表对象:

Base *baseobjects[10];

稍后我用 Derived1Derived2 的实例填充该数组。这适用于 baseobjects[i] = &newDerived1 (其中 newDerived1Derived1 类的实例)。没关系。

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

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

当我尝试编译时,这给了我一个 LNK2019 错误,显然是因为它正在查看 Base< /code> 实现类,但它不存在。我假设我必须使用一些指针技巧来让它查看正确的派生方法,但我尝试过的任何方法都不起作用。有什么建议吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

勿忘心安 2024-10-25 02:54:57

您的方法应声明为虚拟。就您而言,可能是虚拟

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

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

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
};

编辑:

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

要么您忘记了 = 0,要么您从某个地方调用 Base::SomeFunction()

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

如果您对此主题感兴趣,我建议您阅读这篇文章

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.

没︽人懂的悲伤 2024-10-25 02:54:57

如果你想重写一个方法,它必须是虚拟的。

class Base
{
public:
   Base () { }
   virtual 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;
    }
}

If you want to override a method, it must be virtual.

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

Seccond thing is that your derivated classes did not extends of your base-class.

class Derived1 : public Base
{ 
 public:
    Derived1() : Base() { }
    int SomeFunction (int x, int y)
    {
        // actual implementation
        return 4;
    }
}
祁梦 2024-10-25 02:54:57

您必须声明成员函数 SomeFunction()

  1. virtual
  2. abstract

因此 Base 的声明应如下所示:

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

您可以在派生类中省略 virtual 关键字。

You have to declare the member function SomeFunction()

  1. virtual
  2. abstract

So the declaration for Base should look like this:

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

You can omit the virtual keyword in the derived classes.

忱杏 2024-10-25 02:54:57

为了稍微详细说明 ereOn 的答案,您确实需要声明您的基类函数(即:您的抽象定义),以便您的派生类能够覆盖它。但他没有澄清的是,除此之外,您发布的内容很好(也就是说,对您发布的函数的调用将无需任何修改即可工作)。

另请注意,如果您需要纯抽象定义,则应将 = 0 附加到函数声明中,如下所示:

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

这可以让编译器知道从 Base 派生的类必须提供自己的 SomeFunction 实现。

To just slightly elaborate on ereOn's answer, you do need to declare you base class function (ie: your abstract definition) in order for your derived classes to be able to override it. What he didn't clarify though is that other than that, what you've posted is fine (that is, the calls to the function you posted will then work without any modification).

Note also, that if you're after a pure abstract definition, you should append = 0 to your function declaration as follows:

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

This lets the compiler know that classes derived from Base must supply their own implementation of SomeFunction.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文