用于使用带引用的对象向量的C ++语法

时间:2015-01-29 00:25:46

标签: c++ class vector reference

我已经使用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:

}

1 个答案:

答案 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 *更方便,并且向量知道它们的大小,因此您不需要显式跟踪按钮的数量。