【问题标题】:Strange behavior for int / counterint / counter 的奇怪行为
【发布时间】:2012-02-10 12:38:29
【问题描述】:

我正在尝试将一些歌曲添加到类中的向量中。我存储的值之一是表示歌曲的 int 值。它本质上是一个计数器。我添加的第一首歌曲的值应该是 1,第二首歌曲的值应该是 2,依此类推。但它得到了其他奇怪的值,比如大随机数(正数和负数)。我无法理解我做错了什么。这是代码:

#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Jukebox{
public:
  void addSong(string artist, string title, string filename) {
    song s {++songCounter, artist, title, filename};
    Songs.push_back(s);
  }

  void printSong (int song) {
    cout << Songs[song].no << ". ";
    cout << Songs[song].artist << " - ";
    cout << Songs[song].title << " : ";
    cout << Songs[song].filename << endl;
  }

private:
  struct song {
    int no;
    string artist;
    string title;
    string filename;
  };
  vector<song> Songs;
  int songCounter;
};

int main() {
  Jukebox jbox;
  jbox.addSong("U2", "Magnificent", "U2-Magnificent.mp3");
  jbox.addSong("Sting", "Englishman in New York", "Sting-Englishman_in_New_York.mp3");
  jbox.addSong("U2", "One", "U2-One.mp3");
  jbox.printSong(0);
  jbox.printSong(1);
  jbox.printSong(2);
  return 0;
}

更新

好吧,我可能很愚蠢,在尝试实现它之前应该阅读更多关于类的信息。但我想我确实读过,但我仍然不明白。这就是我的班级现在的样子(不起作用):

class Jukebox(): songCounter(0)
 {

public:
  void addSong(string artist, string title, string filename) {
    songCounter++;
    song s {songCounter, artist, title, filename};
    Songs.push_back(s);
  }

  void printSong (int song) {
    cout << Songs[song].no << ". ";
    cout << Songs[song].artist << " - ";
    cout << Songs[song].title << " : ";
    cout << Songs[song].filename << endl;
  }

private:
  int songCounter;
  struct song {
    int no;
    string artist;
    string title;
    string filename;
  };
  vector<song> Songs;
};

最后一句话

好的。从我看到的 c++ 构造器类的示例中,我对它们的工作方式有某种错误的印象。现在我想我得到它一点点。但是语法对我来说仍然很奇怪。但我尝试阅读更多,所以我真的理解它。这是我所做的并且似乎有效:

#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Jukebox {

public:
  void addSong(string artist, string title, string filename) {
    songCounter++;
    song s {songCounter, artist, title, filename};
    Songs.push_back(s);
  }

  void printSong (int song) {
    cout << Songs[song].no << ". ";
    cout << Songs[song].artist << " - ";
    cout << Songs[song].title << " : ";
    cout << Songs[song].filename << endl;
  }

  Jukebox(): songCounter(0) {} // Constructor

private:
  int songCounter;
  struct song {
    int no;
    string artist;
    string title;
    string filename;
  };
  vector<song> Songs;
};

int main() {
  Jukebox jbox;
  jbox.addSong("U2", "Magnificent", "U2-Magnificent.mp3");
  jbox.addSong("Sting", "Englishman in New York", "Sting-Englishman_in_New_York.mp3");
  jbox.addSong("U2", "One", "U2-One.mp3");
  jbox.printSong(0);
  jbox.printSong(1);
  jbox.printSong(2);
  return 0;
}

【问题讨论】:

    标签: c++ class


    【解决方案1】:

    您没有在构造函数中初始化songCounter

    Jukebox(): songCounter(0),//....other members
    

    如果你不初始化它,那么它可能有任何随机值,这会使你的程序处于未定义状态。

    在使用单元化变量时务必小心,这通常会导致未定义行为,您的程序就是一个很好的例子。

    另外,我不确定您的设计,但如果您想将其用作计数器,它可能应该是 static 成员,它维护您的 Song 类的所有对象的状态。
    或者
    您必须在创建 Song 对象时将其显式设置为适当的值。

    好吧,它是 JukeBox 的计数器,而不是 Song 类,所以它仍然可以成为会员。

    【讨论】:

    • 它不必是静态的,作为Jukebox 的成员完全没问题,但它确实需要初始化..
    • 很抱歉问你这个问题。但是你能扩展你的代码 sn-p 一点吗?因为我不明白。之前只知道python,songCounter(0)好像是调用名为songCounter的函数,其实是个变量。当我尝试做我认为您的意思时,它会引发错误。如果您想知道我尝试了什么,我可以更新问题。
    • @NiclasNilsson:没问题。请在 C++ FAQ here 中查看我的这个答案,它详细解释了您的疑问。
    • 哦,谢谢。我更新了问题。但在寻求更多帮助之前,我会先查看常见问题解答 :-)
    • @NiclasNilsson:我看到了你更新的 Q 并且我看到了其中的问题另外,我确信我提供给你的答案链接指出了同样的问题。很高兴学习 :)
    【解决方案2】:

    你没有初始化变量songCounter

    将以下内容添加到Jukebox的类定义中:

    Jukebox(): songCounter(0) {}
    

    【讨论】:

    • 是的。我现在明白了。投票给你!
    【解决方案3】:

    您需要 Jukebox 的构造函数,并且需要将计数器初始化为 0。

    【讨论】:

    • 是的。我现在明白了。投票给你!
    【解决方案4】:

    我认为你应该将 songCounter 初始化为 0。在类的公共部分:

    public Jukebox() : songCounter(0) {}
    

    【讨论】:

    • 是的。我现在明白了。投票给你!
    【解决方案5】:

    你在哪里初始化songCounter?在 C++ 中,默认情况下原语不是零初始化的。你需要添加

    : songCounter(0)
    

    给你的构造函数。

    【讨论】:

    • c/c++中变量的初始化不依赖于它们的类型(无论是原始还是非原始)它取决于声明变量的存储类(static,register等) .
    • 默认初始化涉及调用类类型的默认构造函数,默认初始化数组类型的所有数组元素,否则什么也不做(例如,对于基元)。静态是零初始化的,这是不同的。
    • 是的。我现在明白了。投票给你!
    猜你喜欢
    • 1970-01-01
    • 2017-10-16
    • 2012-10-03
    • 2016-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多