2013-11-22 127 views
3

避免“纯虚函数调用”我有理由新的C++,所以我想道歉,如果这个问题的水平低于这里通常的标准一点点 -在派生类C++

我试图让几个类从具有虚函数定义的基类继承,然后我想创建一个MainClass *数组,它可以包含所有的派生类,以便输出派生的+定义的虚函数。

我收到错误“R6025:纯虚函数调用” - 我不知道为什么,我假设 - 当被调用时 - 使用子类中该函数的更新定义。

这里是我的代码:

基地:

class mitarbeiter 
{ 
public: 
    mitarbeiter(string name, int nummer); 
    ~mitarbeiter(void); 
    virtual void einkommen() = 0; 
protected: 
    string name; 
    int nummer; 

}; 

Derived1:

#include "mitarbeiter.h" 
class lohnempfaenger : public mitarbeiter 
{ 
public: 
    lohnempfaenger(int stundenlohn, int anzahlStunden, string name, int nummer); 
    ~lohnempfaenger(void); 
    void einkommen(); 
private: 
    int stundenlohn; 
    int anzahlStunden; 
}; 

衍生2:

#include "mitarbeiter.h" 
#include <string> 
class angestellter : public mitarbeiter 
{ 
public: 
    angestellter(int gehalt, string name, int nummer); 
    ~angestellter(void); 
    void einkommen(); 
private: 
    int gehalt; 
}; 

实施 “einkommen()” 中衍生1 :

void lohnempfaenger::einkommen() 
{ 
    cout << "Lohnempfaenger, Name: " << this->name << ", Gesamtlohn: " << this->stundenlohn*this->anzahlStunden << "\n"; 
} 

在派生2执行 “einkommen()”:

void angestellter::einkommen() 
{ 
    cout << "Angestellter, Name: " << this->name << ", Einkommen: " << this->gehalt << "\n"; 
} 

阵列的宣言主要方法:

mitarbeiter* mitPtr[5]; 
mitPtr[0] = &angestellter(/*values...*/); 
//error 
mitPtr[0]->einkommen(); 

构造:

mitarbeiter::mitarbeiter(string name, int nummer) 
{ 
    this->name = name; 
    this->nummer = nummer; 
} 

angestellter::angestellter(int gehalt, string name, int nummer):mitarbeiter(name, nummer) 
{ 
    this->gehalt = gehalt; 
} 

lohnempfaenger::lohnempfaenger(int stundenlohn, int anzahlStunden, string name, int nummer):mitarbeiter(name, nummer) 
{ 
    this->stundenlohn = stundenlohn; 
    this->anzahlStunden = anzahlStunden; 
} 

由于一个很多!

+3

你可以尝试整理一个我们可以在单个步骤中编译的独立示例文件吗? –

+1

void angestellter :: einkommen();应该声明为虚拟 – jbh

+3

与你的问题无关,但'mitarbeiter'的析构函数应该是'virtual',否则如果你通过指向'mitarbeiter'的'instance'删除派生实例,你将会得到Udefined Behavior。 – Angew

回答

7

现在你告诉我们,你实际上是如何初始化的指针,现在的问题是:

mitPtr[0] = &angestellter(/*values...*/); 

指向一个临时对象,它在声明的最后销毁。之后使用指针会导致未定义的行为。

你需要一个非临时变量指向:

angestellter a(/*values...*/); 
mitPtr[0] = &a; 

或者是一个动态分配的对象:

mitPtr[0] = new angestellter(...); 

在这种情况下,不要忘记将其删除;并且不要忘记给基类一个虚拟析构函数,以便它可以被删除。您可能会考虑使用智能指针为您删除它; std::unique_ptr将是理想的。

+0

啊,我明白 - 我从来没有想过会对它产生影响 - 谢谢! –

+3

@Dennis为了记录,你得到“纯虚拟调用”的原因是因为调用析构函数时,它会将类的vtable重置为下一个。因此,当调用'〜angestellter'时,它会将类的函数重置为'mitarbeiter'的函数 - 这就是为什么如果您尝试在'〜angestellter'中调用'einkommen()'时会遇到同样的问题。所以当你调用'einkommen()'时你访问的是无效内存,但是内存可能仍然包含它的最后一个有效内容,这是指向基类中纯标记的指针。 –

0

我猜你在运行时看到的错误消息是说mitarbeiter :: einkommen()被调用。

你的主代码声称是分配一个新的天使,其代码你没有提供,但有几个可能的地方,这个电话可以隐藏。

如果mitarbeiter :: mitarbeiter调用einkommen(),无论您指定给新的类型是什么类型,都会得到mitarbeiter :: einkommen()。这似乎是最有可能的地方。

其他可能性是明确调用angestellter :: angestellter()或angestellter :: einkommen()中完全合格的mitarbeiter :: einkommen()。