伊莉討論區

標題: (已解決)關於class中 給予列舉初始值的問題 (追問)class中的 static const char*的初始化 [打印本頁]

作者: 在那裡    時間: 2018-10-26 05:16 PM     標題: (已解決)關於class中 給予列舉初始值的問題 (追問)class中的 static const char*的初始化

本帖最後由 在那裡 於 2018-10-28 11:26 PM 編輯

小弟最近想要寫一個俄羅斯方塊,但卻在賦予初始值得地方卡住了,問題點在於如何隨機給予列舉值。
程式碼為簡化只給予必需的程式碼

----Tetris.h-----
#ifndef TETRIS_H_
#define TETRIS_H_


.....

namespace WordColor
{
    enum Color
    {
        Black = 0,
        Bule = 1,
        Green = 2,
        Cyan = 3,
        Red = 4,
        Violet = 5,
        Yellow = 6,
        White = 7,
        Gray = 8
    };

    bool SetWordColor(Color word, bool word_intensity ,Color background, bool background_intensity);
}


.....

class Tetris
{
private:
   ....
   const WordColor::Color color; //record enum Color.
   ....
public:
   ....
}
#endif //TETRIS_H_


----Tetris.cpp------

//class Tetris
//error: invalid conversion from 'int' to 'WordColor::Color' [-fpermissive]|
Tetris::Tetris(int X, int Y) : color(rand()%9)  
{
     ....
}



問題就是出在 Tetris.cpp 中 的建構函數, rand()%9 中, int無法成功轉換成enum Color型別,
請問大大們有什麼方法可以讓小弟的俄羅斯方塊可以隨機產生顏色呢?


作者: baepi    時間: 2018-10-26 11:40 PM

color(rand()%9)  
改成這樣?
color = (WordColor::Color)(rand() % 9);
以下是剛剛隨手測試....使用VS2017
  1. namespace WordColor
  2. {
  3.         enum Color
  4.         {
  5.                 Black = 0,
  6.                 Bule = 1,
  7.                 Green = 2,
  8.                 Cyan = 3,
  9.                 Red = 4,
  10.                 Violet = 5,
  11.                 Yellow = 6,
  12.                 White = 7,
  13.                 Gray = 8
  14.         };
  15. }
  16. void main()
  17. {
  18.         const WordColor::Color color = (WordColor::Color)(rand() % 9);
  19.         cout << color << endl;
  20.         system("pause");
  21. }
複製代碼

作者: 在那裡    時間: 2018-10-27 12:02 AM

本帖最後由 在那裡 於 2018-10-27 12:06 AM 編輯
baepi 發表於 2018-10-26 11:40 PM
color(rand()%9)  
改成這樣?
color = (WordColor::Color)(rand() % 9);

不行,強制轉型也試過了
Tetris::Tetris(int X, int Y) : color((WordColor::Color)rand()%9)  
{
     ....
}
不過單獨編譯你的程式碼卻是成功的

作者: baepi    時間: 2018-10-27 09:28 AM

前篇我只是想表達enum不能直接用int...須強制轉型
結果您沒注意到自己設定的const
以下是程式碼...依舊是VS2017下測試OK
  1. #include <time.h>
  2. namespace WordColor
  3. {
  4.         enum Color
  5.         {
  6.                 Black = 0,
  7.                 Bule = 1,
  8.                 Green = 2,
  9.                 Cyan = 3,
  10.                 Red = 4,
  11.                 Violet = 5,
  12.                 Yellow = 6,
  13.                 White = 7,
  14.                 Gray = 8
  15.         };
  16. }
  17. class aa
  18. {
  19. private:
  20.         const WordColor::Color color = (WordColor::Color)(rand() % 9);
  21. public:
  22.         aa();
  23.         void get_color();
  24. };
  25. aa::aa()
  26. {
  27. }
  28. void aa::get_color()
  29. {
  30.         cout << color << endl;
  31. }
  32. void main()
  33. {
  34.         srand(time(NULL));
  35.         aa bb[2];
  36.         bb[0].get_color();
  37.         bb[1].get_color();
  38.         system("pause");
  39. }
複製代碼

作者: z1090128    時間: 2018-10-27 01:43 PM

我記得rand是給0~1之間的隨機值嗎???
所以%9時都會變0??
作者: 在那裡    時間: 2018-10-28 02:23 AM

本帖最後由 在那裡 於 2018-10-28 02:36 AM 編輯
baepi 發表於 2018-10-27 09:28 AM
前篇我只是想表達enum不能直接用int...須強制轉型
結果您沒注意到自己設定的const
以下是程式碼...依舊是VS ...

抱歉
我注意到我自己的錯誤在哪了。
將程式碼改寫成
Tetris::Tetris(int X, int Y) : color( (WordColor::Color)(rand()%9) )  
{
     ....
}
即可運行。
之前程式碼問題出在rand()先被強制轉型為enum Color後才被進行%9運算,才導致了錯誤。

不過這與const無關,類別建構函數可以使用":"來設定 const與reference的初始值。但我覺得還是將初始值設定寫入class中好了。
感謝回答,問題已解決!
作為結論,enum Color若要由其他型別(ex: int, char, float, double...)一定必須進行強制轉型才能寫入,而不能自動轉換。

p.s:
有個問題雖然已經找到解決方法,但還是感到疑惑
在class Tetris中,有個static const char* BLOCK = "abc"產生了錯誤,但static const int MAX_SHAPE = 3;卻沒出錯,這是為什麼呢? BLOCK的值在.cpp的實作檔重新定義了所以解決了,但我還是感到疑惑。

----Tetris.h----
class Tetris
{
private:
// error: 'constexpr' needed for in-class initialization of static data member 'const char* Tetris::BLOCK' of non-integral type [-fpermissive]|
    static const char* BLOCK = "abc";
    static const int MAX_SHAPE = 3; //it is OK
}

----Tetris.cpp-----
//若在Tetris.h中沒有幫BLOCK設置"abc"
const char* Tetris::BLOCK = "abc"; //it is OK


作者: baepi    時間: 2018-10-28 06:17 PM

在那裡 發表於 2018-10-28 02:23 AM
抱歉
我注意到我自己的錯誤在哪了。
將程式碼改寫成

呵呵...請抱歉我眼殘多年...應該是不治之症了
當初我會說const...是因為我以為您是打
  1. aa::aa()
  2. {
  3.         color = (WordColor::Color)(rand() % 9);
  4. }
複製代碼
結果您是使用
  1. aa::aa() : color((WordColor::Color)(rand() % 9))
  2. {
  3. }
複製代碼
所以這部份是我眼殘所致...抱歉抱歉
另外您說為何static const 變數可以直接宣告設定...為何陣列就不行...關於這個...可能要請您查查原文解說了..以前看過說明...感覺不重要...也就無視了...如果真覺得礙眼...想要少寫一行...可以改成
  1. class aa
  2. {
  3. private:
  4.          static const char *BLOCK() { return "abc"; }
  5. public:
  6.         void get_block();
  7. };
  8. void aa::get_block()
  9. {
  10.         cout << BLOCK() << endl;
  11. }
  12. void main()
  13. {
  14.         aa bb;
  15.         bb.get_block();
  16. }
複製代碼

作者: 在那裡    時間: 2018-10-28 11:25 PM

baepi 發表於 2018-10-28 06:17 PM
呵呵...請抱歉我眼殘多年...應該是不治之症了
當初我會說const...是因為我以為您是打結果您是使用所以這 ...

關於這一部分我會再自己翻翻文獻的,畢竟這並不是大礙,只是單純感到好奇而已。
謝謝回答~
作者: johnwanz    時間: 2018-10-30 08:37 AM

在那裡 發表於 2018-10-28 11:25 PM
關於這一部分我會再自己翻翻文獻的,畢竟這並不是大礙,只是單純感到好奇而已。
謝謝回答~ ...

看起來, 似乎, 只有支持整數形式的初始化. (不知道自己是否有理解錯誤)

附上看到的參考資料.

C++ standard, 9.4.2/4:
If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression. In that case, the member can appear in integral constant expressions within its scope. The member shall still be defined in a namespace scope if it is used in the program and the namespace scope definition shall not contain an initializer.


[stackoverflow] How to declare a static const char* in your header file?




歡迎光臨 伊莉討論區 (http://a04.eyny.com/) Powered by Discuz!