2015-01-13 35 views
0

[编辑帖子,基于之前的回答和评论。我已经尝试了几种策略,其中没有任何一种可行。]带指针变量的C++分段故障类

我有一个类D,带有类型为E的成员变量.E有两个子类,E1和E2。当我尝试下面的代码时,我遇到了分段错误(请参阅下面的详细输出)。有人能告诉我为什么,并提供更改的代码,将使其工作?谢谢。

任何有关可接受或专业编码风格的意见都会受到欢迎。


#include <iostream> 
#include <vector> 

using std::cout; 
using std::endl; 
using std::vector; 

class E { 
    public: 
     E() {cout << "In E constructor" << endl;} 

     virtual ~E() {cout << "In E destructor" << endl;} 
}; 

class E1 : public E { 
    public: 
     E1() {cout << "New E1" << endl;} 

     ~E1() {cout << "In E1 destructor" << endl;} 
}; 

class E2 : public E { 
    public: 
     E2() {cout << "New E2" << endl;} 

     ~E2() {cout << "In E2 destructor" << endl;} 
}; 

class D { 
    public: 
     D(const vector<int>& a, int b) 
     { 
      cout << "y1" << endl; 
      if (b == 1) 
       p = new E1(); 
      else 
       p = new E2(); 
     } 

     D() {cout << "y2" << endl; p = new E1();} 

     ~D() {if (p != nullptr) {cout << "x" << endl; delete p;}} 

    private: 
     E *p; 
}; 

int main(int argc, char **argv) 
{ 
    D d; 

    vector<int> a; 
    a.push_back(1); 

    int b = 2; 

    d = D(a, b); 
} 

这里的输出。

y2 
In E constructor 
New E1 
y1 
In E constructor 
New E2 
x 
In E2 destructor 
In E destructor 
x 
Segmentation fault 
+0

http://meta.stackexchange.com/a/129632/165773 – gnat

+2

你的问题已经正确说明,但在Programmers SE上这是题外话。由于@gnat已经链接,您可以在网站的策略中找到与主题相关的设计问题与应该针对Stack Overflow的实现问题之间的分离。 – logc

回答

0

由于声明,您的原始代码会删除新的E2对象。

d = D(a, b); 

由于您没有提供赋值运算符,因此编译器将提供成员赋值实现。紧接着分配之后,变量d和从D(a,b)创建的临时的未命名的变量将具有指向相同E2对象的成员变量p

将在d和未命名的变量上调用D ::〜D()析构函数。删除E2对象会导致分段错误。

+0

我删除了删除语句,程序工作。然后,我将delete语句更改为'if(p!= nullptr)delete p'。我再次遇到了分段错误。任何见解?谢谢。 –

+0

@ tr1944您的默认构造函数不会将p初始化为nullptr,因此您不确定它的值。 – user2313067

+0

默认的复制赋值运算符(和复制构造函数)执行*成员*的复制,而不是按位复制。不是说这对原始类型有很大的实际区别。 –