2015-09-10 74 views
1

问题这个程序为什么会崩溃?我错误地分配了内存吗?

设计一个具有名称和员工编号的员工类。派生经理,科学家和劳动者班。经理类拥有额外的属性标题和会费。科学家类有额外的属性数量的出版物。劳工阶级没有什么额外的。这些类具有设置和显示信息的必要功能。

我的解决方案

#include<iostream> 
#include<cstring> 
using namespace std; 
class employee 
{ 
protected: 
    char *name; 
    int number; 
public: 
    employee() 
    { 
     cout<<"enter employee name \n"; 
     cin>>name; 
     cout<<"enter employee number \n"; 
     cin>>number;   
    } 
    void display() 
    { 
     cout<<"name \t"<<name<<endl; 
     cout<<"number \t"<<number<<endl; 
     // inside class function is a inline function 
    }   
}; 
class manager: private employee 
{ 
    float due; 
    char *title; 
    public: 
    manager() 
    { 
     cout<<"due\t "<<endl; 
     cin>>due; 
     cout<<"title\t"<<endl; 
     cin>>title; 
     fflush(stdin); 
    } 

    void display() 
    { 
     employee::display();  //inside class function is a inline function 
     cout<<"due\t"<<due<<endl; 
     cout<<"title\t"<<title<<endl; 
     //inside class function is a inline function 
    } 
}; 
class labour :private employee 
{ 
public: 

    void display() 
    {  
     employee::display();  //inside class function is a inline function 
    } 
}; 
class Scientist :private employee 
{ 
    int number; 
public: 
    Scientist() 
    {  
     cout<<"publication number "<<endl; 
     cin>>Scientist::number; 
    } 

    void display()     
    { 
     employee::display(); 
     cout<<" pub number "<<Scientist::number<<endl; 
     fflush(stdin); 
    } //inside class function is a inline function 

}; 

int main() 
{ 
    manager m; 
    m.display();   
    Scientist s; 
    s. display(); 
    labour l; 
    l.display(); 
    return 0; 
} 
+0

不要使用C字符串 - 因为这应该是C++,然后使用'std :: string'。也不要叫'fflush(stdin)' - 它最好不可移植,最坏的情况是UB。正确格式化代码也是一个好主意。 –

+1

'fflush(stdin);'是未定义的。不要这样做。 – molbdnilo

+1

构造函数不应该以任何方式与用户交互。 – molbdnilo

回答

3

你不分配任何内存为titlename,所以你不能从std::cin读入他们。而不是使用char*的你应该使用std::string这将做所有的分配给你:

std::string title; 
std::string name; 
0

empolyee你读的构造成一个未初始化char*。因此它并不指向可以存储输入名称的有效内存块。你可以做

name = static_cast<char*>(malloc(32 * sizeof(char))); 

分配内存,使名称指向有效内存,但你总是浪费内存或没有足够的输入。你也必须释放析构函数中的内存。

正如Peter Schneider在此答案的评论中所写的那样,另一种选择是使用固定大小的数组作为成员,例如,

char name[MAX_NAME_LENGTH]; 

与例如,预处理器定义

#define MAX_NAME_LENGTH 64 

在您的文件的顶部。这样复制构造函数完成他的工作。使用指针作为成员,您总是必须自己编写它们,否则,原始类实例和复制实例将具有指向相同内存的成员指针。因此,如果复制的实例更改名称,原始实例的名称也会更改。

最简单的解决方案是使用std::string而不是char*。它自己分配内存,您不必释放任何东西,复制也可以正常工作。

+1

如果std :: strings不可用我只需定义一个数组'char name [MAX_NAME_LEN];',避免明确释放该数组的需要。 –

+1

顺便说一句,复制和分配也更简单,即隐式,与数组成员。 –

+0

我给你的答案加了你的建议。感谢那。 – Gombat