c++ - C ++将类传递给构造函数=不传递相同的实例?
问题描述
似乎,当我传递一个类时,它并没有像我期望的那样传递该类的持久(相同)实例。我假设这与记忆状态有关,但如果有人能准确解释正在发生的事情,我将不胜感激。该问题很容易证明如下:
主程序
#include "Debug.h"
#include "Box.h"
Debug debug;
Box box(debug);
void loop(){
debug.message("loop");
debug.line();
}
void setup(){
debug.init();
box.init();
debug.message("Setup Complete");
debug.line();
}
调试.h
#ifndef DEBUG_H
#define DEBUG_H
class Debug {
private:
bool state;
public:
Debug();
void init();
void message(const char *str);
void message(int);
void line();
};
#endif
调试.cpp
#include "Debug.h"
#include <Arduino.h>
Debug::Debug() : state(false) {}
void Debug::init() {
if (state == false){
Serial.begin(9600);
state = true;
}
}
void Debug::message(const char *messageChar) {
if (state){
const char *p;
p = messageChar;
while (*p) {
Serial.print(*p);
p++;
}
}
}
void Debug::message(int messageInt) {
if (state){
Serial.print(messageInt);
}
}
void Debug::line() {
if (state){
Serial.println();
}
}
盒子.h
#ifndef BOX_H
#define BOX_H
#include "Debug.h"
class Box {
private:
Debug debug;
public:
Box(Debug &debug);
void init();
};
#endif
盒子.cpp
#include "Box.h"
#include <Arduino.h>
Box::Box(Debug &debug):
debug(debug)
{}
void Box::init(){
// Switches
pinMode(28, INPUT_PULLUP);
debug.message("Box intialized");
debug.line();
}
所以上面的代码输出到串口:
Setup Complete
如果我将 Box::init() 修改为
void Box::init(){
// Switches
pinMode(28, INPUT_PULLUP);
debug.init();
debug.message("Box intialized");
debug.line();
}
我得到了我想要的:
Box initialized
Setup Complete
如果我摆脱 Box 构造函数类,而是做
void Box::init(Debug &debug){
this->debug = debug;
// Switches
pinMode(28, INPUT_PULLUP);
debug.message("Box intialized");
debug.line();
}
通过 Main.ino 调用
void setup(){
debug.init();
box.init(debug);
debug.message("Setup Complete");
debug.line();
}
我再次得到了想要的回应。我不明白为什么我的第一次尝试不起作用,也不知道什么是最佳实践让我感到不舒服。我将不胜感激任何指导。
解决方案
您的代码中有两个Debug
值。一个全局,一个Box
类的成员。
这是两个不同的值,因为Box
从一个值创建或复制以创建它自己的值,并且是全局值。
一种解决方案是包含引用或指针。
这是带有参考的示例:
class Box {
private:
Debug& debug;
// ^---- there
public:
Box(Debug &debug);
void init();
};
如果您Box
仍然想分配,请使用指针:
class Box {
private:
Debug* debug;
// ^---- now it's a star
public:
Box(Debug &debug);
void init();
};
Box::Box(Debug &debug):
debug(&debug)
{} // ^----- here, we take the address of the debug variable.
由于引用是不可变的,因此您失去了该语言的一些重要特性:赋值。
struct thing {
int& ref;
};
int main () {
int a, b;
thing t1{a}, t2{b};
t1 = t2; // ERROR!
}
赋值会导致t1.ref
指向b
后赋值。
指针具有更难的语法和难以猜测的语义。但是,它们在分配方面表现得非常好,因为它们给了你更多的自由:
struct thing {
int* ptr;
};
int main () {
int a, b;
thing t1{&a}, t2{&b};
t1 = t2; // Works, t1.ptr points to b
}
推荐阅读
- group-policy - 无法使用此 GPO 组合用户是 X 组的成员并且用户不是 Y
- php - Drupal 8 或 9 将数据从自定义模块保存到内容类型
- c++ - 尝试使用 Cocos2D-x C++ 调用初始化函数
- react-native - 如何修复 React Native Navigator 不起作用
- github - 如何验证 SSH 指纹?
- symfony - SYMFONY 5 - Form EntityType 不使用数据库中的 id,而是使用名称
- javascript - 如何使用 JavaScript 在另一个页面中获取图像 src?
- android - 从 Android 原生 C++ 代码管理 SQLite
- r - 在 R 中按组和按时间计算最大值
- install4j - 无法将 Java 1.8.271 x64 添加到 Install4j Build