【问题标题】:C++ Constructor error. Cannot initialize array of stringsC++ 构造函数错误。无法初始化字符串数组
【发布时间】:2011-03-23 22:23:28
【问题描述】:

为什么不能在我的构造函数中初始化我的字符串数组?我收到以下错误: 内部编译器错误:分段错误|

在构造函数的这两行: 西装= {“俱乐部”,“钻石”,“红心”,“黑桃”}; 面额 = {"Ace","2","3","4","5","6","7","8","9","10","Jack","Queen" "国王"};

class Card
    {
      public:
        Card(int n);
        Card(string d, string s);
        int getNumber();
        string getDenomination();
        string getSuit();
        void setNumber(int n);
        void setDenomination(string d);
        void setSuit(string s);
        void printMe();
        void compareMe(Card c);

      private:
        int number;
        string denomiation;
        string suit;
        string suits [4];
        string denominations [13];
    };


    Card::Card(int n)
    {
        suits = {"Clubs", "Diamonds", "Hearts", "Spades"};
        denominations = {"Ace","2","3","4","5","6","7","8","9","10","Jack","Queen","King"};

        int denIndex, suitIndex;

        denIndex = 51 % 13;
        suitIndex = 51 / 13;

        number = n;
        denomiation = denominations[denIndex];
        suit = suits[suitIndex];

    }

【问题讨论】:

  • 你的错误编译器叫什么名字?
  • 您不是在尝试初始化它,而是在尝试分配它,而复合语法(大括号内的一堆值)不适用于分配。

标签: c++ arrays constructor initialization


【解决方案1】:

根据您发布的代码,我猜suitsdenominations 成员应该是静态数据成员,也就是说,对于每个Card 实例,它们将始终具有相同的数据。

所以我建议你将它们设为静态并在你的 cpp 文件的文件范围内初始化它们(在你的类声明之外):

声明:

class Card
{
  public:
    Card(int n);
    Card(string d, string s);
    int getNumber();
    string getDenomination();
    string getSuit();
    void setNumber(int n);
    void setDenomination(string d);
    void setSuit(string s);
    void printMe();
    void compareMe(Card c);

  private:
    int number;
    string denomiation;
    string suit;
    static const string suits [4];                 // static const
    static const string denominations [13];        // static const
};

定义:

const string Card::suits[4] = {"Clubs", "Diamonds", "Hearts", "Spades"};
const string Card::denominations[13] = {"Ace","2","3","4","5","6","7","8","9","10","Jack","Queen","King"};

编辑: 正如 Robert S. Barnes 所说,将它们设为 static const 会更好。

希望对您有所帮助。

【讨论】:

  • 如何处理复杂类型?我知道像char* 这样的简单类型,编译器会获取数据,将其放入只读部分,然后将指针设置为指向它。这会做类似的事情,而是在运行时调用= 运算符吗?声明不应该是static const吗?
  • 这个调用数组初始化器(为每个元素调用单参数构造函数),它使用复合初始化语法。没有复合赋值语法。
  • +1,花色和面额列表并不特定于一副牌中的每张牌,而是特定于一副牌本身。
  • 好点,我会删除显式的大小规范,你可以让编译器为你推导出它string Card::suits[] = {/*.*/};
  • @Robert S. Barnes: static const 更好。改变了。
【解决方案2】:

你只能在构造时使用字面量数组初始化,而不是赋值。

int good[3] = { 1, 2, 3 }; // OK
int bad[3];
bad = { 1, 2, 3 }; // not so good

您必须手动复制数组(或使用vectorboost::array 之类的容器。

【讨论】:

    【解决方案3】:

    如果您遇到 ICE(内部编译器错误),那么您确实应该将代码报告给编写您的编译器的人。编译器应该打印出警告和错误,而不是分段错误。

    【讨论】:

      【解决方案4】:

      使用std::vectorboost::array,您的代码的简化示例如下

      #include <boost/assign/list_of.hpp>
      
      #include <boost/array.hpp>
      
      #include <iostream>
      #include <string>
      
      class Card
      {
      public:
          explicit Card( unsigned n ) :
              _number( n ),
              _suits( boost::assign::list_of( "Clubs" )( "Diamonds" )( "Hearts" )( "Spades" ) ),
              _denominations( boost::assign::list_of( "Ace" )( "2" )( "3" )( "4" )( "5" )( "6" )( "7" )( "8" )( "9" )( "10" )( "Jack" )( "Queen" )( "King" ) )
          {
      
          }
      
      private:
          unsigned _number;
          boost::array<std::string, 4> _suits;
          boost::array<std::string, 13> _denominations;
      };
      
      int
      main()
      {
          Card foo( 5 );
      
          return 0;
      }
      

      【讨论】:

      • 这是一个很好的建议,但对手头的问题没有帮助,即您不能分配这样的数组文字。如果你试图用向量做这种事情,你也会遇到同样的问题。
      • @Ferruccio:不正确,语法称为“初始化器列表”,将在 c++0x 中完全支持。在这里使用 std::vector 仍然是更好的选择。
      • 投反对票:我已经用一些示例代码更新了我的答案
      • 我明白了。如果没有示例,您似乎在说保持代码不变,但使用向量而不是内置数组。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-03
      • 2011-05-25
      • 1970-01-01
      • 2011-01-25
      相关资源
      最近更新 更多