奇怪的访问冲突错误

时间:2012-12-28 22:45:18

标签: c++ access-violation

我编写了一个使用继承的程序,一切都还可以,但我认为不应该自然而然地出现错误。 这是我的计划:

class A
{
protected:
    int x;
public:
    A(){};
    ~A(){};
    A* operator=(const A* other)
    {
        this->x = other->x;
        return this;
    }
};
class B : public A
{
public:
    B() : A(){};
    ~B(){};
};
class C
{
protected:
    A *a;
public:
    C(const A* other){ *(this->a) = other; };
};

int main()
{
    B *b = new B();
    C *c = new C(b);
    return 0;
}

它在语句中产生执行时间错误' this-> x = other-> x;'。 那怎么样?

2 个答案:

答案 0 :(得分:7)

*(this->a)是未定义的行为,因为this->a未初始化 - 它只是一个悬空指针。

您可以使用a = new A; *a = other(在这种情况下this->是多余的),但这不是正确的C ++方式 - 您应该使用RAII(查找它) - 您不需要析构函数,赋值运算符或复制构造函数,如果你这样做的话。

此外,operator =通常会通过引用返回*this

答案 1 :(得分:2)

我喜欢Luchian的答案,但代码中仍有一些地方需要增强,在修复其他潜在错误之前,您可能仍会在代码中遇到一些未定义的行为。

class A
{
protected:
    int x;
public:
    A():x(0){}     // should always initialize x in constructor
    virtual ~A()=0 {} // as A is a base case, ~A must be virtual
    A& operator=(const A& other)  // a reference will be more practical better?
    {
        this->x = other.x;
        return *this;
    }
};

如果您不想制作B对象,这意味着B作为基类提供服务,您应该将其析构函数设置为虚拟,甚至使其成为纯虚拟对象。

class B : public A
{
public:
    B() : A(){}
    virtual ~B(){} =0
    { }       
};
Luchian已经回复了{p> *(this->a) = other;。在你的代码中,如果你想保留一个指向A的指针副本,你只需在member initialize list中初始化a_ptr即可。 见下面的演示代码:

class C
{
protected:
   A *a_ptr;
public:
    C(A* other):a_ptr(other){ }
};

最后来到你的main函数,如果b,c只在main函数中使用,当程序完成时,系统将声明动态分配的内存,但如果在循环中使用a,b,则需要删除他们手动。