简体   繁体   English

奇怪的访问冲突错误

[英]A strange access violation error

I have wrote a program that use inheritance, everything is OK but an error that I think shouldn't not be here naturally. 我写了一个使用继承的程序,一切都还可以,但我认为这个错误不应该在这里自然而然。 here is my program: 这是我的计划:

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;
}

It produces an execution time error in the statement 'this->x = other->x;'. 它在语句'this-> x = other-> x;'中产生执行时错误。 What about this? 那这个呢?

*(this->a) is undefined behavior, because this->a wasn't initialized - it's just a dangling pointer. *(this->a)是未定义的行为,因为this->a没有初始化 - 它只是一个悬空指针。

You can use a = new A; *a = other 你可以使用a = new A; *a = other a = new A; *a = other (the this-> in this case is redundant), but this isn't the proper C++ way - you should use RAII (look it up) - you wouldn't need destructors, assignment operators or copy constructors if you did. a = new A; *a = otherthis->在这种情况下是冗余的),但这不是正确的C ++方式 - 你应该使用RAII(查找它) - 如果你不需要析构函数,赋值运算符或复制构造函数没有。

Also, operator = typically returns *this by reference. 此外, operator =通常通过引用返回*this

I like Luchian's answer but there is still some places to enhanced in your code, you may still encounter some undefined behavior in your code before you fix other potential bugs. 我喜欢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;
    }
};

If you don't want to make B object as well which means B is serviced as a base class, you should make its destructor virtual as well, even make it pure virtual. 如果你不想制作B对象,这意味着B被作为基类服务,你应该将它的析构函数设置为虚拟,甚至使它成为纯虚拟的。

class B : public A
{
public:
    B() : A(){}
    virtual ~B(){} =0
    { }       
};

*(this->a) = other; is answered by Luchian already. Luchian已经回答了。 In your code, if you want to keep a copy of pointer which points to A, you can simply initialize a_ptr in member initialize list see below demo code: 在你的代码中,如果你想保留一个指向A的指针副本,你只需在member initialize list初始化a_ptr,参见下面的演示代码:

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

Finally come to your main function, if b,c are only used in main function, when program finishes, system will claim dynamic allocated memory back, but if you use a,b in a loop, you need to delete them manually. 最后来到你的main函数,如果b,c只用在main函数中,当程序完成时,系统将声明动态分配的内存,但如果你在循环中使用a,b ,则需要手动删除它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM