取消引用指向容器 class 成员的指针
Dereferencing pointer to container class member
我有以下问题需要解决。我从一个大 class P 开始,我想将其拆分。因此,部分功能已移至新的 class 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;
}
我要classQ负责改P.x。为此,我认为在创建时将对 P.x 的引用传递给 Q 是可行的。但是,这会导致分段错误。 有没有办法让Q能够访问和修改x?原因是我最终想要有多个classes Q1,Q2等,都负责对 P.x 的不同操作,其中 P.x 将是比简单的 int 更复杂的数据类型。
您的问题是因为您对函数参数和 class 成员使用了相同的变量名。虽然这是允许的,但它是(恕我直言),非常 不好的做法。如果要保留名称,则需要在需要区分两者的函数中添加显式 this->
,否则您的参数名称将 'shadow' 和 class 成员.
因此,您的 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
定义默认构造函数的评论 - 您可以删除此 provided 您在 'required' 参数时你 declare/instatiate P
中的 q
成员:
class P {
public:
Q q{ nullptr }; // BEWARE: You can NEVER use this object as it stands!
int x;
//...
我有以下问题需要解决。我从一个大 class P 开始,我想将其拆分。因此,部分功能已移至新的 class 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;
}
我要classQ负责改P.x。为此,我认为在创建时将对 P.x 的引用传递给 Q 是可行的。但是,这会导致分段错误。 有没有办法让Q能够访问和修改x?原因是我最终想要有多个classes Q1,Q2等,都负责对 P.x 的不同操作,其中 P.x 将是比简单的 int 更复杂的数据类型。
您的问题是因为您对函数参数和 class 成员使用了相同的变量名。虽然这是允许的,但它是(恕我直言),非常 不好的做法。如果要保留名称,则需要在需要区分两者的函数中添加显式 this->
,否则您的参数名称将 'shadow' 和 class 成员.
因此,您的 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
定义默认构造函数的评论 - 您可以删除此 provided 您在 'required' 参数时你 declare/instatiate P
中的 q
成员:
class P {
public:
Q q{ nullptr }; // BEWARE: You can NEVER use this object as it stands!
int x;
//...