如果这是一个非常基本的问题,你将不得不原谅我;我很长一段时间没有使用过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];
稍后我用Derived1
和Derived2
的实例填充该数组。这适用于baseobjects[i] = &newDerived1
(其中newDerived1
是Derived1
类的实例)。这一切都很好。
我似乎无法弄清楚如何稍后遍历baseobjects
数组并在列表中的每个实例上调用SomeFunction
,而不明确知道我是哪个派生类使用。我在C#中完成了这个并且它工作正常,但显然我的C ++语法已关闭:
int result = baseobjects[i]->SomeFunction(a, b);
当我尝试编译时,这给了我一个LNK2019
错误,显然是因为它正在查看实现的Base
类,但它不存在。我假设我必须使用一些指针技巧来让它看看正确的派生方法,但我尝试过的任何东西都没有用。有什么建议吗?
答案 0 :(得分:8)
您的方法应声明为virtual
。在您的情况下,可能纯 virtual
。
class Base
{
public:
Base () { }
virtual int SomeFunction (int x, int y) = 0; // abstract definition
};
请注意,虽然这不是绝对必需的,但您也可以声明一个virtual
析构函数。如果您通过基类的指针删除派生实例,请执行此操作。
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
并不意味着你的函数没有实现:它可以有一个,但它只需要派生类(重新)实现它不是抽象。
如果您对此主题感兴趣,建议您阅读this post。
答案 1 :(得分:2)
如果要覆盖方法,则必须是虚拟的。
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;
}
}
答案 2 :(得分:1)
您必须声明成员函数SomeFunction()
所以Base的声明应如下所示:
class Base
{
public:
Base() { }
virtual int SomeFunction(int x, int y) = 0;
};
您可以省略派生类中的虚拟关键字。
答案 3 :(得分:0)
为了稍微详细说明ereOn的答案,你做需要声明你的基类函数(即:你的抽象定义),以便你的派生类能够覆盖它。他没有澄清的是,除此之外,你发布的内容很好(也就是说,你发布的函数的调用将在没有任何修改的情况下工作)。
另请注意,如果您正在使用纯抽象定义,则应将= 0
附加到函数声明中,如下所示:
class Base
{
public:
Base () { }
virtual int SomeFunction (int x, int y) = 0; // pure abstract definition
};
这使编译器知道从Base
派生的类必须提供自己的SomeFunction
实现。