简体   繁体   English

取消引用指向容器 class 成员的指针

[英]Dereferencing pointer to container class member

I have the following problem I want to be solved.我有以下我想解决的问题。 I started out with a large class P, which I wanted to split up.我从一个大的 class P 开始,我想把它分开。 Therefore a part of the functionality was moved to a new class Q. However, I do not seem to be able to make these two communicate properly.因此,部分功能被移至新的 class Q。但是,我似乎无法使这两者正常通信。 To make this a bit more visual, I made this toy example:为了让这更直观一点,我做了这个玩具示例:

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

I want the class Q to be responsible for changing Px To do this, I thought that passing a reference to Px to Q when it's created would work.我希望 class Q 负责更改 Px 为此,我认为在创建 Q 时将对 Px 的引用传递给它会起作用。 However, this results in a segmentation fault.但是,这会导致分段错误。 Is there a way to make Q able to access and modify x?有没有办法让 Q 能够访问和修改 x? The reason for this is that I eventually want to have a number of classes Q1, Q2 etc, which are all responsible for different operations on Px, where Px will be a more complicated data type than a simple int.这样做的原因是我最终想要有许多类 Q1、Q2 等,它们都负责 Px 上的不同操作,其中 Px 将是比简单的 int 更复杂的数据类型。

Your problems arise from the fact that your are using the same variable names for both function arguments and class members.您的问题源于您对 function arguments 和 class 成员使用相同的变量名这一事实。 Although this is allowed, it is (IMHO), very bad practice.虽然这是允许的,但它是(恕我直言),非常糟糕的做法。 If you want to keep the names, then you will need to add an explicit this-> in the functions where you need to distinguish between the two, otherwise your argument names will 'shadow' the class members.如果要保留名称,则需要在需要区分两者的函数中添加显式this-> ,否则您的参数名称将“隐藏” class 成员。

So, your Q constructor, keeping the name-clashes, would need to be:因此,保持名称冲突的Q构造函数需要:

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

and your P constructor would be:你的P构造函数将是:

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

However, with simple name-changes to the arguments, this is much clearer:但是,通过对 arguments 进行简单的名称更改,这将更加清晰:

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

As it stands, in your code, the line q = Q(&x);就目前而言,在您的代码中,行q = Q(&x); in the P constructor passes the address of the temporary object given as the argument, which causes a memory error (segmentation fault) when you later try to modify it.P构造函数中,将临时 object 的地址作为参数传递,这会在您稍后尝试修改它时导致 memory 错误(分段错误)。

Note: On your comment about not having to define a default constructor for Q - you can remove this provided you give the 'required' parameter when you declare/instatiate the q member in P :注意:关于不必为Q定义默认构造函数的评论 - 如果您在声明/实例化P中的q成员时提供“必需”参数,则可以删除它:

class P {
public:
    Q q{ nullptr }; // BEWARE: You can NEVER use this object as it stands!
    int x;
//...

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

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