2009-07-23 5 views
1

Я просто изучаю C++, исходя из фона Java.C++ String array issue

Просто играть вокруг с простых классов теперь, но по какой-то причине следующий не будет компилировать, когда тот же синтаксис компилируется нормально в другом месте:

class CardDealer { 

    private: 
     string suits[4]; 
     string values[13]; 
     bool cardTaken[4][13]; 
     int getRand(int top); 
     void getValidSuit(int *suit); 
     void getValidCard(int suit,int *value); 

    public: 
     CardDealer(); 
     string dealCard(); 
     void resetDeck(); 
}; 

CardDealer::CardDealer(){ 
    suits = {"hearts", "clubs", "spades", "diamonds"}; 
    values = {"ace","two","three","four","five","six","seven","eight","nine","ten","jack","queen","king"}; 
    cardTaken = {{false,false,false,false,false,false,false,false,false,false,false,false,false},{false,false,false,false,false,false,false,false,false,false,false,false,false}, 
    {false,false,false,false,false,false,false,false,false,false,false,false,false},{false,false,false,false,false,false,false,false,false,false,false,false,false}}; 
} 

, очевидно, что это просто часть класса так пожалуйста, не «т кричать на меня не хватает„}“s

компилятор патроны шаткий, когда он попадает в инстанциацию в конструкторе, выплевывает ошибки, подобные этим:


1>.\CardDealer.cpp(26) : error C2059: syntax error : '{' 
1>.\CardDealer.cpp(26) : error C2143: syntax error : missing ';' before '{' 
1>.\CardDealer.cpp(26) : error C2143: syntax error : missing ';' before '}' 
1>.\CardDealer.cpp(27) : error C2059: syntax error : '{' 
1>.\CardDealer.cpp(27) : error C2143: syntax error : missing ';' before '{' 
1>.\CardDealer.cpp(27) : error C2143: syntax error : missing ';' before '}' 
1>.\CardDealer.cpp(28) : error C2059: syntax error : '{' 

линия 26 является тот, в котором я инстанцирован костюмы (suits = { ...)

спасибо за Взглянув ребята, высоко ценится

ответ

6

До C++ 0x вы можете использовать синтаксис агрегатного инициализатора (т. Е. Фигурные скобки) при объявлении массива.

Обратите внимание, что эта программа дает подобную ошибку:

int thing[4]; 
int main() 
{ 
    thing = { 0, 1, 2, 3 }; 
} 

Вы должны инициализировать массив с несколько утомительным синтаксисом скобки, один элемент одновременно.

+0

ugh, thats gasty. Я не мог заставить его работать при инициализации, поэтому мне пришлось идти по одному по времени маршруту. ваше право, очень утомительно. спасибо! –

+0

Это не единственное решение, но вы можете сохранить фиксированные инициализаторы в отдельном массиве (возможно, в массиве const char *) и просто скопировать их в переменные экземпляра класса с одним вызовом std :: copy в конструкторе. –

0

Поскольку мы не знаем, весь исходный файл, мы не знаем, что находится в строках 26, 27, 28. Я предполагаю, что код:

cardTaken = {{false,..... 

поднимает эти ошибки. Вместо этой очень длительной инициализации вы можете использовать:

for(int i = 0; i<4; i++) 
{ 
    for(int j = 0; j<13; j++) 
    { 
     cardTaken[i][j] = false; 
    } 
} 

Таким образом, ваш код станет более понятным и понятным.

+0

Извините за неясность, строка 26 - это то, где я создал экземпляр 'suits'. отредактированный пост для ясности –

4

я исправил ранее пост:

Вы можете инициализировать их, как это за пределами класса:

namespace CardDealer 
{ 
    static const string suits[] = {"hearts", "clubs", "spades", "diamonds"}; 
    static const string values[]={"ace","two","three","four","five","six","seven","eight","nine","ten","jack","queen","king"}; 

    class CardDealer 
    {  
    private: 
     bool cardTaken[4][13]; 
     ... 
    }; 

    ... 
} 

В конструкторе можно инициализировать cardTaken в цикле.

+0

Я только что пробовал выше, но компилятор дает те же ошибки. спасибо в любом случае –

+3

Только встроенные элементы могут быть инициализированы внутри определения класса. – CiscoIPPhone

+0

Что вы подразумеваете под интегральным элементом? как в целом? или что-то еще полностью ... –

0

Вы можете удалить часть скуки, используя что-то подобное в своем конструкторе.

const char* tempSuits[] = {"hearts", "clubs", "spades", "diamonds"}; 
for(int i=0; i<4; ++i) suits[i] = tempSuits[i]; 

Вы можете использовать фигурные скобки синтаксис для инициализации строк C-стиле, которые вы можете присвоить STD :: строки.

Вы можете также использовать строки стиля C в своем классе для начала (тогда вам не понадобится цикл).

0

Простое решение:

class CardDealer { 

    private: 
     const string suits[4]; 
     const string values[13]; 
     bool cardTaken[4][13]; 
     int getRand(int top); 
     void getValidSuit(int *suit); 
     void getValidCard(int suit,int *value); 

    public: 
     CardDealer(); 
     string dealCard(); 
     void resetDeck(); 

    private: 
     static string suits_initializer[4]; 
     static string values_initializer[13]; 
}; 


CardDealer::CardDealer(){ 
    memcpy(suits, suits_initializer, sizeof(suits)); 
    memcpy(values, values_initializer, sizeof(values)); 
    memset(cardTaken, 0, sizeof(cardTaken)); 
} 

string CardDealer::suits_initializer[4] = {"a","b","c","d"}; 

это работает, до тех пор, костюмы и значения постоянны .. но на самом деле, вам нужно их как переменные экземпляра? статические требования и статические значения достаточно для вас, в этом примере.

+0

Использование memcpy для типов классов, таких как std :: string, очень опасно! –

1

Первый вопрос, который возникает, необходим suits и values для массивов на объекты или они могут совместно использоваться всеми экземплярами CardDealer?

Если нет, я бы сделал их статическими, а затем вы можете предоставить синтаксис статической инициализации, который вы пытаетесь использовать в своей точке определения.

E.g.

class CardDealer { 

    private: 
     static const std::string suits[4]; 
     static const std::string values[13]; 

    // ... 
}; 

и в .cc/.cpp файл в другом месте:

const std::string CardDealer suits[4] = { "hearts", " ... ", ... }; 
const std::string CardDealer values[13] = { "ace", " ... ", ... }; 

Если они должны быть в классе, и это лишь некоторые начальные значения, то я бы предпочел, чтобы сделать их вектор строк инициализируют их из некоторых статически выделенных строк C. например .:

class CardDealer { 

    private: 
     static const char* init_suits[4]; 
     static const char* init_values[13]; 

     std::vector<std::string> suits; 
     std::vector<std::string> values; 

    // ... 
}; 

CardDealer::CardDealer() 
    : suits(init_suits, init_suits + sizeof init_suits/sizeof init_suits[0]) 
    , values(init_values, init_values + sizeof init_values/sizeof init_values[0]) 
{ 
} 

const char* CardDealer::init_suits[4] = { ... }; 
const char* CardDealer::init_values[13] = { ... }; 

Что касается вашего массива cardTaken как 0 превращается в false вы можете просто по умолчанию инициализировать члена в списке initalizer вашего конструктора.

CardDealer::CardDealer() 
    : suits(init_suits, init_suits + sizeof init_suits/sizeof init_suits[0]) 
    , values(init_values, init_values + sizeof init_values/sizeof init_values[0]) 
    , cardTaken() 
{ 
} 
0

Вы можете использовать повышение :: Присвоить:

#include <string> 
#include <vector> 
#include <boost/assign.hpp> 
#include <boost/assign/list_of.hpp> 
#include <boost/assign/std/vector.hpp> 

const std::vector<std::string> my_vector_of_strings = 
boost::assign::list_of("cat")("dog")("banana")("apple")(orange)("tuna")("salmon")("dinosaur")("blablabla")("...")("etc")("etc")("etc"); 

Забавная вещь, вы можете объявить СТЛ контейнеры как consts используя эту полезную библиотеку, так как ваши массивы, представляющие карты и значения не изменяются , Я бы, вероятно, объявлял их как consts, и я использовал бы векторы, поскольку они безопаснее использовать, а не классические массивы.