我有以下问题要解决。我从大班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更为复杂的数据类型。
您的问题是由于您为函数参数和类成员使用相同的变量名而引起的。尽管允许这样做,但这是(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;
//...