C++:如何将对象传递给另一个对象构造函数?
C++: how to pass an object to another object constructor?
我知道很多人问这个问题,但我来自 Java 并且我已经很长时间没有做过任何 C/C++ 了。
你能提醒我如何在 C++ 中正确地将一个对象传递给另一个对象的构造函数吗?
例如,我需要将一个新的 Light 对象传递给 Button 构造函数:
// LED Light
class Light {
int pin;
public:
Light(int p) {
pin = p;
}
};
// BUTTON
class Button {
Light ledLight;
public:
Button(Light l) {
ledLight = l;
}
};
Light my_led(0);
Button my_button(my_led);
这就是我在 Java 风格中的做法。
但是,这会产生以下错误:
:: In constructor ‘Button::Button(Light)’:
:: 16:19: error: no matching function for call to ‘Light::Light()’
:: 16:19: note: candidates are:
:: 6:3: note: Light::Light(int)
:: 6:3: note: candidate expects 1 argument, 0 provided
:: 2:7: note: Light::Light(const Light&)
:: 2:7: note: candidate expects 1 argument, 0 provided
当我创建新 Button 时,对象是通过引用传递还是试图创建一个新对象?
或者我是否需要在 Button 的构造函数中将 Light 声明为指针?
非常感谢任何帮助!
该程序尝试使用默认构造函数启动 ledLight
,然后将 l
分配给 ledLight
。编译器给你一个错误,因为 Light
没有默认构造函数。试试这个:
Button(Light l): ledLight(l) { }
您缺少默认构造函数。尝试像这样修改您的 class:
class Light {
int pin;
public:
Light()=default; //<-- put this in
Light(int p) {
pin = p;
}
};
至于为什么你不自动生成默认构造函数,那是因为你已经声明了某种类型的构造函数,所以编译器不会生成默认构造函数(来自 http://en.cppreference.com/w/cpp/language/default_constructor,参见关于隐式 declared/defined 构造函数的部分。
回复评论:
Wouldn't it attempt to call the default constructor instead of the one
which passes the arguments?
当您的执行代码到达最后一行时:
Button my_button(my_led);
您正在实例化 Button
和 Light
作为 Button
实例化过程的一部分。如果不指定默认 Light::Light()
构造函数,您将遗漏有关如何实例化没有值的 Light
对象的说明,您需要在将 my_led
的值复制到 my_button。你会得到你想要的结果,你只是目前遗漏了编译器关于如何执行中间步骤的指令,即实例化 Light
没有任何参数。
一些需要思考的事情:
您真正想做什么?只需查看您的指令代码:
Light my_led(0);
Button my_button(my_led);
在我看来,你好像在说 "a light named my_led
exists" 和 "a button named my_button
exists and needs my_led
"。您希望按钮指向已存在的特定 LED,还是仅指向具有相同值的 LED?
如果您认为自己想要参考该按钮的实际 LED,那么您可能需要考虑执行以下操作:
class Button {
const Light *ledLight;
public:
Button(const Light& l) :
ledLight{&l}
{}
};
这样,您的 Button
就有一个指向您创建的 Light
的指针,无论您对 Button
代码中的 Light
做什么,都将在您已经实例化的 Light
对象,而不是您通过使用当前 Button
构造函数复制构造 Light
创建的 Light
的一些单独副本。
如果您想让按钮实际修改灯光,请像这样修改Button
:
class Button {
// constant reference to changeable object
Light * const ledLight;
public:
/**
* You're providing a reference to a light that can be changed
* (i.e. button code can toggle lit status or something)
*/
Button(Light & l) :
ledLight{&l}
{}
};
以上你可以认为是从按钮到 LED 有一根不变的电线。如果您认为您将重新分配从按钮点亮的 LED,您也可以从 Button
中的指针成员中取出 const
关键字。
我知道很多人问这个问题,但我来自 Java 并且我已经很长时间没有做过任何 C/C++ 了。
你能提醒我如何在 C++ 中正确地将一个对象传递给另一个对象的构造函数吗?
例如,我需要将一个新的 Light 对象传递给 Button 构造函数:
// LED Light
class Light {
int pin;
public:
Light(int p) {
pin = p;
}
};
// BUTTON
class Button {
Light ledLight;
public:
Button(Light l) {
ledLight = l;
}
};
Light my_led(0);
Button my_button(my_led);
这就是我在 Java 风格中的做法。 但是,这会产生以下错误:
:: In constructor ‘Button::Button(Light)’:
:: 16:19: error: no matching function for call to ‘Light::Light()’
:: 16:19: note: candidates are:
:: 6:3: note: Light::Light(int)
:: 6:3: note: candidate expects 1 argument, 0 provided
:: 2:7: note: Light::Light(const Light&)
:: 2:7: note: candidate expects 1 argument, 0 provided
当我创建新 Button 时,对象是通过引用传递还是试图创建一个新对象?
或者我是否需要在 Button 的构造函数中将 Light 声明为指针?
非常感谢任何帮助!
该程序尝试使用默认构造函数启动 ledLight
,然后将 l
分配给 ledLight
。编译器给你一个错误,因为 Light
没有默认构造函数。试试这个:
Button(Light l): ledLight(l) { }
您缺少默认构造函数。尝试像这样修改您的 class:
class Light {
int pin;
public:
Light()=default; //<-- put this in
Light(int p) {
pin = p;
}
};
至于为什么你不自动生成默认构造函数,那是因为你已经声明了某种类型的构造函数,所以编译器不会生成默认构造函数(来自 http://en.cppreference.com/w/cpp/language/default_constructor,参见关于隐式 declared/defined 构造函数的部分。
回复评论:
Wouldn't it attempt to call the default constructor instead of the one which passes the arguments?
当您的执行代码到达最后一行时:
Button my_button(my_led);
您正在实例化 Button
和 Light
作为 Button
实例化过程的一部分。如果不指定默认 Light::Light()
构造函数,您将遗漏有关如何实例化没有值的 Light
对象的说明,您需要在将 my_led
的值复制到 my_button。你会得到你想要的结果,你只是目前遗漏了编译器关于如何执行中间步骤的指令,即实例化 Light
没有任何参数。
一些需要思考的事情:
您真正想做什么?只需查看您的指令代码:
Light my_led(0);
Button my_button(my_led);
在我看来,你好像在说 "a light named my_led
exists" 和 "a button named my_button
exists and needs my_led
"。您希望按钮指向已存在的特定 LED,还是仅指向具有相同值的 LED?
如果您认为自己想要参考该按钮的实际 LED,那么您可能需要考虑执行以下操作:
class Button {
const Light *ledLight;
public:
Button(const Light& l) :
ledLight{&l}
{}
};
这样,您的 Button
就有一个指向您创建的 Light
的指针,无论您对 Button
代码中的 Light
做什么,都将在您已经实例化的 Light
对象,而不是您通过使用当前 Button
构造函数复制构造 Light
创建的 Light
的一些单独副本。
如果您想让按钮实际修改灯光,请像这样修改Button
:
class Button {
// constant reference to changeable object
Light * const ledLight;
public:
/**
* You're providing a reference to a light that can be changed
* (i.e. button code can toggle lit status or something)
*/
Button(Light & l) :
ledLight{&l}
{}
};
以上你可以认为是从按钮到 LED 有一根不变的电线。如果您认为您将重新分配从按钮点亮的 LED,您也可以从 Button
中的指针成员中取出 const
关键字。