Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 类定义中有多个公共/私有关键字_C++_C++11 - Fatal编程技术网

C++ 类定义中有多个公共/私有关键字

C++ 类定义中有多个公共/私有关键字,c++,c++11,C++,C++11,我在类定义中看到了多个公共和私有关键字,如下例所示: class myClass { public: void func1(){} public: void func2(){} private: int x; int y; private: int z; int baz; }; 这个(如果有的话)的实际用途是什么?在任何情况下,这可能有用吗 我将用一段代码进一步说明我对这个答案的评论 class myClass { //

我在类定义中看到了多个公共和私有关键字,如下例所示:

class myClass
{
  public:
    void func1(){}
  public:
    void func2(){}
  private:
    int x;
    int y;
  private:
    int z;
    int baz;
};

这个(如果有的话)的实际用途是什么?在任何情况下,这可能有用吗

我将用一段代码进一步说明我对这个答案的评论

class myClass {

    // initializers etc
    public:
        myClass();
        ~myClass();

    // signal processing
    public:
        void modifyClass();
    private:
        float signalValue;

    // other class responsibilities
    public:
        void doWork();
    private:
        void workHelper();
};
等等。我不会说这是一个坚实的类设计,但它是一个展示类的不同功能的好方法

在任何情况下,这是否有用

我可以想到一种情况,如果不是这样的话,问题会非常严重:

 class myClass
{
  public:
    void func1(){}
  public:
    void func2(){}
  COORDINATES;    // <-- Note the macro here!
  private:
    int z;
    int baz;
};
如果不允许使用多个
private
/
public
关键字,那么这样做会非常痛苦。虽然使用宏不是一个好的实践;对于宏后面出现的所有成员,也没有悄悄地引入访问修饰符。但是,它对于生成C++源代码的RAD工具可能是有用的。
我只能猜测你为什么会在人类写作课上看到这一点。我的猜测是,这是糟糕的编码;作者可能想表示一个数据块属于一起,并且/或者希望能够在类定义中上下移动这些数据块,以及相应的访问修饰符(
private/protected/public
)。让我们考虑两种情况:

  • 坏案例

    // Auxiliary class
    Class StorageCleaner {
    public:
        StorageCleaner(ExternalStorage* storage) : storage_(storage);
        ~StorageCleaner() { storage_->DeleteEverything(); }
    private:
        ExternalStorage* const storage_;  // Not owned
    }
    
    // Class with bad declaration order
    Class ExternalStorageWrapper {
    public:
        ExternalStorageWrapper(ExternalStorage* storage) : cleaner_(storage) {
            pointer_to_storage_.reset(storage);
        }
        const StorageCleaner cleaner_;  
    private:
        std::unique_ptr<ExternalStorage> pointer_to_storage_;
    
        // Other data which should be private
        int other_int;
        string other_string;
        .... 
    };
    
    当现有的
    ExternalStorageWrapper
    对象超出范围时,会发生什么情况

    • ExternalStorageWrapper析构函数将首先销毁其他数据
    • 然后它将尝试销毁
      清洁器
      。Cleaner将使用指向仍然存在的存储器的指针从存储器中删除所有内容
    • 最后,通过
      指向存储的指针
      破坏存储

  • 事实上,我不得不在一家公司调试这样的问题,所以尽管这种情况很少见,但这种特殊的情况是可能发生的

    为了清晰起见,我遇到了一个用例。如下面的示例所示,
    class1
    继承了
    base
    类,该类包含
    class1
    需要实现的纯虚拟函数。为了表明
    class1
    中的
    method1
    来自另一个类
    class1
    继承自(例如
    base
    )而不是
    class1
    自身的函数,我们使用另一个
    public
    来说明这一点:

    class base {
    public:
       virtual void method1() = 0;
    }
    
    class class1: base {
    public:
       myOwnMethod1();
       myOwnMethod2();
    public: /* base interface */
       method1();
    

    刚刚读完这些例子。希望这一个可以有助于多关键字定义是多么有用。 我们不需要假设太多,因为这是我目前的问题,但需要消耗以下资源:

    class IOHandler { public: enum COLOR_DEFINITIONS : unsigned char { BLACK, DARK_ER_BLUE, DARK_GREEN, DARK_SKY_BLUE, DARK_RED, DARK_PINK, DARK_YELLOW, DARK_WHITE, DARK_GREY, DARK_BLUE, BRIGHT_GREEN, BRIGHT_SKY_BLUE, BRIGHT_RED, BRIGHT_PINK, BRIGHT_YELLOW, BRIGHT_WHITE }; template <typename dtEX> void showOutputEx(dtEX literalOutput, _COLOR_OUTPUT textColorSet = {COLOR_DEFINITIONS::BRIGHT_WHITE , COLOR_DEFINITIONS::BRIGHT_YELLOW}, bool appendOutputType = true, OUTPUT_TYPE levelOutput = OUTPUT_TYPE::OUTPUT_NORMAL, EMBRACE_TYPE embraceOutputType = EMBRACE_TYPE::EMBRACE_OUTPUT_LEVEL, ...); // ! ^^^^^^^^^^^^^^ Doesn't detect the struct being referenced at which is at below. private: typedef struct colorProps // This is the struct that the public function where trying to get referenced at but failed to do so. { unsigned char C_BG = 0, C_FG = 0; } _COLOR_OUTPUT; }; 此时,我的intelliSense不断抱怨
    \u COLOR\u OUTPUT
    在公共类范围内未定义。 最可能的解决方案是将结构放在公共范围而不是私有范围内。 但我不想

    发生这种情况的原因是编译器从上到下读取文件。申报的任何东西 需要参考的应该放在最上面,这应该解决问题。因为我不想把所有私有类函数和变量都放进去,把事情搞得一团糟 在上面。我应该在顶部声明另一个说明符,这样任何需要引用的公共函数都可以看到前面的说明符

    因此,解决方案如下:(将所有可引用变量和结构移到类的顶部,以便识别任何私有和公共函数参数引用。)

    类IOHandler{ //变量和结构的私有类范围 私人: typedef struct colorProps//这是我们在顶部移动以识别引用的结构。 { 无符号字符C_BG=0, C_FG=0; }彩色输出; 公众: 枚举颜色定义:无符号字符 { 黑色 深蓝色, 深绿色, 深蓝的天空, 深红色, 深粉色, 深黄色, 深白, 深灰色, 深蓝色, 鲜绿色, 明亮的天蓝, 鲜红, 亮粉色, 亮黄, 亮白 }; 模板 void showOutputEx(dtEX literalOutput,_COLOR_OUTPUT textColorSet={COLOR_DEFINITIONS::BRIGHT_WHITE,COLOR_DEFINITIONS::BRIGHT_YELLOW},bool appendOutputType=true,OUTPUT_TYPE levelOutput=OUTPUT_TYPE::OUTPUT_NORMAL,拥抱_TYPE拥抱_outputType=拥抱_TYPE::拥抱_OUTPUT_LEVEL,…); //!^^^^^^^^^^^^^^^现在可识别参考。 私人: …//任何其他函数,摘录。 };
    除了美学之外,你认为这还有什么实际用途?我的意思是,你总是可以重新排序的方法,使你只需要一个单一的关键字每个这就是为什么我问。我不确定是否有一些隐藏的原因,我还没有发现…这就是为什么我好奇地把这个问题贴在上面,所以我过去使用这些问题的主要原因是为了从视觉上分离我班上的各种关注点。我将设置组,在这些组的公共成员和私有成员之间交替,等等。您可能会关心子对象的初始化顺序。@EJP是新手……我看到一些代码是由我尊敬的人编写的,不知道这是否有很好的理由,或者是一次事故。我不确定我能不能称之为可靠的——仅仅说:
    public://初始化者等等…/,有什么不对信号处理…//其他…
    之后是相同的顺序,现在是
    private
    ?这样,作为代码的读者,我所关心的公共接口仍然位于类的顶部,我不必在声明的内部寻找它
    class base {
    public:
       virtual void method1() = 0;
    }
    
    class class1: base {
    public:
       myOwnMethod1();
       myOwnMethod2();
    public: /* base interface */
       method1();
    
    class IOHandler { public: enum COLOR_DEFINITIONS : unsigned char { BLACK, DARK_ER_BLUE, DARK_GREEN, DARK_SKY_BLUE, DARK_RED, DARK_PINK, DARK_YELLOW, DARK_WHITE, DARK_GREY, DARK_BLUE, BRIGHT_GREEN, BRIGHT_SKY_BLUE, BRIGHT_RED, BRIGHT_PINK, BRIGHT_YELLOW, BRIGHT_WHITE }; template <typename dtEX> void showOutputEx(dtEX literalOutput, _COLOR_OUTPUT textColorSet = {COLOR_DEFINITIONS::BRIGHT_WHITE , COLOR_DEFINITIONS::BRIGHT_YELLOW}, bool appendOutputType = true, OUTPUT_TYPE levelOutput = OUTPUT_TYPE::OUTPUT_NORMAL, EMBRACE_TYPE embraceOutputType = EMBRACE_TYPE::EMBRACE_OUTPUT_LEVEL, ...); // ! ^^^^^^^^^^^^^^ Doesn't detect the struct being referenced at which is at below. private: typedef struct colorProps // This is the struct that the public function where trying to get referenced at but failed to do so. { unsigned char C_BG = 0, C_FG = 0; } _COLOR_OUTPUT; };
    identifier "_COLOR_OUTPUT" is undefined.
    
    class IOHandler { // Private Class Scope for Variables and Structure private: typedef struct colorProps // This is the struct we move at the top for recognizing references. { unsigned char C_BG = 0, C_FG = 0; } _COLOR_OUTPUT; public: enum COLOR_DEFINITIONS : unsigned char { BLACK, DARK_ER_BLUE, DARK_GREEN, DARK_SKY_BLUE, DARK_RED, DARK_PINK, DARK_YELLOW, DARK_WHITE, DARK_GREY, DARK_BLUE, BRIGHT_GREEN, BRIGHT_SKY_BLUE, BRIGHT_RED, BRIGHT_PINK, BRIGHT_YELLOW, BRIGHT_WHITE }; template <typename dtEX> void showOutputEx(dtEX literalOutput, _COLOR_OUTPUT textColorSet = {COLOR_DEFINITIONS::BRIGHT_WHITE , COLOR_DEFINITIONS::BRIGHT_YELLOW}, bool appendOutputType = true, OUTPUT_TYPE levelOutput = OUTPUT_TYPE::OUTPUT_NORMAL, EMBRACE_TYPE embraceOutputType = EMBRACE_TYPE::EMBRACE_OUTPUT_LEVEL, ...); // ! ^^^^^^^^^^^^^^ Now recognizable reference. private: ... // Any other functions, excerpt. };