引用指向容器类成员的指针

问题描述 投票:0回答:1

我有以下问题要解决。我从大班P开始,我想将其拆分。因此,功能的一部分已移至新的类Q。但是,我似乎无法使这两者正确通信。为了使它更直观,我制作了这个玩具示例:

#include <iostream>

class Q {
public:
    int* x_ptr;

    Q(){ } // Is there any way to not have to write default constructors?

    Q(int* x_ptr){
        x_ptr = x_ptr;
    }

    void say_x(){
        std::cout << *x_ptr << std::endl;
    }

    void change_x(){
        *x_ptr += 1;
    }
};

class P {
public:
    Q q;
    int x;

    P(int x){
        x = x;
        q = Q(&x);
    }
};

int main(){
    P my_p = P(10);
    my_p.q.say_x();
    my_p.q.change_x();
    std::cout << my_p.x << std::endl;
}

我希望班级Q负责更改P.x。为此,我认为将P.x的引用在创建时传递给Q是可行的。但是,这会导致分段错误。 是否有使Q能够访问和修改x的方法?这样做的原因是,我最终希望拥有许多类Q1,Q2等,它们都负责Px上的不同操作,其中Px比简单的int更为复杂的数据类型。

c++ pointers segmentation-fault dereference scoping
1个回答
0
投票

您的问题是由于您为函数参数和类成员使用相同的变量名而引起的。尽管允许这样做,但这是(IMHO)的错误做法。如果要保留名称,则需要在函数中添加一个显式的this->,以便在两者之间进行区分,否则参数名称将'shadow'该类成员。因此,您的Q构造函数将保持名称冲突,应为:

Q(int* x_ptr) { this->x_ptr = x_ptr; }

您的P构造函数将是:

P(int x) { this->x = x; q = Q(&(this->x)); }

但是,只要对参数进行简单的名称更改,就更清楚了:

Q(int* arg_x_ptr) { x_ptr = arg_x_ptr; } //... P(int arg_x) { x = arg_x; q = Q(&x); }

就目前而言,在您的代码中,q = Q(&x);构造函数中的行P传递作为参数指定的临时对象的地址,这将在以后尝试对其进行修改时导致内存错误(分段错误)。 

注意:关于不必为Q定义默认构造函数的评论-您可以删除此[[provided

,当您在q中声明/实例化P成员时提供'required'参数:

class P { public: Q q{ nullptr }; // BEWARE: You can NEVER use this default-constructed object! int x; //...

© www.soinside.com 2019 - 2024. All rights reserved.