我有以下问题需要解决。我从一个很大的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等,它们都负责对P.x的不同操作,其中P.x将是比简单的int更复杂的数据类型。有没有办法让Q能够访问和修改x>
您的问题源于您对函数参数和类成员使用相同的变量名。尽管这是允许的,但这是(IMHO(,非常的不良做法。如果要保留名称,则需要在需要区分两者的函数中添加显式this->
,否则参数名称将"遮蔽"类成员。
因此,保持名称冲突的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);
}
目前,在您的代码中,P
构造函数中的q = Q(&x);
行传递了作为参数给定的临时对象的地址,这会在您稍后尝试修改它时导致内存错误(分段错误(。
注意:在您关于不必为Q
定义默认构造函数的评论中,您可以删除提供的。当您在P
:中声明/初始化q
成员时,您会给出"必需"参数
class P {
public:
Q q{ nullptr }; // BEWARE: You can NEVER use this object as it stands!
int x;
//...