我已经使用C很长一段时间了,但是我想在当前项目中使用C ++面向对象的样式,因为它看起来更适合这种方法。所以,我宁愿成为C ++最佳实践的新手,我希望有人可以帮我弄清楚如何做到这个希望直截了当的事情。
我花了最后一周阅读这个网站和教程学习有关引用,将它们传递给函数,初始化另一个类中的静态类成员,以及其他一些我很高兴知道的东西,但我认为我从初学者的角度来看每个人的基本想法,我很难跟上如何把它们放在一起。
这是我为编写概念性理解而编写的思想实验程序。
在这里,我定义了一个“Button”类,其中包含一些当前微不足道的成员。
然后我定义了一个“Wand”类,它在概念上是将按钮组织成一组按钮的方法。
编辑:基于Steven的有用回复,我更新了我的代码以尝试他的建议布局。这对我来说很有意义。我修了一些我认为可能是错别字的小东西,但我觉得有一些微妙的关于.back我做错了。我为std :: string编写了“String”,因为它是一个Arduino。#include <vector>
class Button {
private:
bool _active;
String _title;
float _value;
public:
Button(String title, float value) : _title(title) , _value(value) {}
void setButton(bool active) {
_active = active;
};
String getTitle(void) {
return _title;
};
float getValue(void) {
return _value;
};
void setValue(float newvalue) {
_value = newvalue;
};
};
class Wand {
private:
std::vector<Button> _Buttons;
int _numButtons;
public:
Wand() {};
Button& addButton(String title, float value) {
_Buttons.push_back(Button(title, value));
return _Buttons.back();
}
Button& getButton(int number) {
return _Buttons[number];
};
int numButtons(void) {
return _Buttons.size();
};
};
void setup() {
// put your setup code here, to run once:
SerialUSB.begin(9600);
Wand wand = Wand();
Button& OkButton = wand.addButton("Okay Button", 0);
Button& NokayButton = wand.addButton("Nokay Button", 0);
while(1) {
SerialUSB.println(wand.getButton(0).getTitle() + "(via Wand): "+ wand.getButton(0).getValue());
SerialUSB.println(OkButton.getTitle() + "(via Button): "+ OkButton.getValue());
SerialUSB.println(wand.getButton(1).getTitle() + "(via Wand): "+ wand.getButton(1).getValue());
SerialUSB.println(NokayButton.getTitle() + "(via Button): "+ NokayButton.getValue());
OkButton.setValue(OkButton.getValue()+1);
NokayButton.setValue(NokayButton.getValue()-1);
delay(500);
}
}
void loop() {
// put your main code here, to run repeatedly:
}
现在对我来说真的很奇怪,尽管两个按钮看似平行的结构,我从显示器得到的响应是这样的:
(via Wand): 0.00
(via Button): 15.00
(via Wand): -15.00
(via Button): -15.00
(via Wand): 0.00
(via Button): 16.00
(via Wand): -16.00
(via Button): -16.00
显然我正确地更新并访问第二个按钮,但是第一个似乎又创建了两个类的实例,即未更新的魔杖实例和引用的版本。
原始邮件:
现在,我已经阅读了关于std :: vector的内容,它似乎是一种在Wand中存储动态分配的按钮数组的自然方式。但是当我使用Wand的成员函数来读取值时,很明显我没有使用最初分配的Button对象。
在此代码中,我看到实际按钮更改的值,但通过Button向量请求时的值是不同的。我试过投入一些&符号,但它主要是造成编译器错误。
有谁能告诉我如何正确地做这种事情?或者,如果这是完全错误的方法,那么如何学习以更标准的方式做到这一点的链接?
#include <vector>
class Button {
private:
bool _active;
char* _title;
float _value;
public:
Button(char* title, float value) : _title(title) , _value(value) {}
void setButton(bool active) {
_active = active;
};
char* getTitle(void) {
return _title;
};
float getValue(void) {
return _value;
};
void setValue(float newvalue) {
_value = newvalue;
};
};
class Wand {
private:
std::vector<Button> _Buttons;
int _numButtons;
public:
Wand() {};
void addButton(Button &newbutton) {
_Buttons[_numButtons] = newbutton;
_numButtons++;
};
Button& getButton(int number) {
return _Buttons[number];
};
int numButtons(void) {
return _numButtons;
};
};
void setup() {
// put your setup code here, to run once:
SerialUSB.begin(9600);
Wand wand = Wand();
Button OkButton = Button("Okay Button", 0);
Button NokayButton = Button("Nokay Button", 0);
wand.addButton(OkButton);
wand.addButton(NokayButton);
while(1) {
SerialUSB.println(wand.getButton(0).getValue());
SerialUSB.println(OkButton.getValue());
OkButton.setValue(OkButton.getValue()+1);
SerialUSB.println(wand.getButton(1).getValue());
SerialUSB.println(NokayButton.getValue());
NokayButton.setValue(NokayButton.getValue()-1);
delay(500);
}
}
void loop() {
// put your main code here, to run repeatedly:
}
答案 0 :(得分:0)
当你向魔杖添加按钮时,你正在向量中添加一个副本,因此向量中按钮的地址与OkButton和NoOkButton的地址不同。
正如其他人指出的那样使用std :: vector&lt; std :: unique_ptr&gt;可能是最强大的解决方案。但是,如果你真的想使用矢量&lt;按钮&gt;您可以创建对矢量完成后按钮的可编辑引用。这有点危险,因为std :: vector保证了连续的内存,因此如果没有空间,添加新元素时,各个元素的地址可能会发生变化。这是代码(未经测试):
#include <vector>
class Button {
private:
bool _active;
std::string _title;
float _value;
public:
Button(std::string title, float value) : _title(title) , _value(value) {}
void setButton(bool active) {
_active = active;
};
std::string getTitle(void) {
return _title;
};
float getValue(void) {
return _value;
};
void setValue(float newvalue) {
_value = newvalue;
};
};
class Wand {
private:
std::vector< Button > _Buttons;
public:
Wand() {};
void addButton( std::string title, float value ) {
_Buttons.push_back( Button( title, value ) );
};
Button& getButton(int number) {
return _Buttons[number];
};
int numButtons(void) {
return _Buttons.size();
};
};
void setup() {
// put your setup code here, to run once:
SerialUSB.begin(9600);
Wand wand = Wand();
wand.addButton("Okay Button", 0);
wand.addButton("Nokay Button", 0);
// If you add buttons after this, these references
// may be invalid.
Button& OkButton = wand.getButton(0);
Button& NokayButton = wand.getButton(1);
while(1) {
SerialUSB.println(wand.getButton(0).getValue());
SerialUSB.println(OkButton.getValue());
OkButton.setValue(OkButton.getValue()+1);
SerialUSB.println(wand.getButton(1).getValue());
SerialUSB.println(NokayButton.getValue());
NokayButton.setValue(NokayButton.getValue()-1);
delay(500);
}
}
void loop() {
// put your main code here, to run repeatedly:
}
我也冒昧地展示了stl的其他一些功能。 std :: string通常比char *更方便,并且向量知道它们的大小,因此您不需要显式跟踪按钮的数量。