1

私は OOP を学ぶ最初の一歩を踏み出しています。そして、これが私が解決できない最初の問題です。このクラスの max 関数は、最大 2 つの数値を返す必要があります。数値はプライベート スコープに、関数はパブリック スコープに保持したいと考えています。struct data{}しかし、パブリックスコープの変数を使用したい場合、コンパイラは変数が宣言されていないと言います。これらのエラーが発生する理由を教えてください。

class myclass{
private:
   struct data{
       int q ;
       int w;
   };

public:
   void get(int a, int b){
      struct data = {a , b}; // here I want to pass the variables to data struct
   }
   int max (){              // this function returns the biggest number 
      if(q>w)
         return q;
         else 
            return w;
   } 

};
4

3 に答える 3

2

C++ では、「クラス」と「構造体」はほとんど同義語です (同じことです)。唯一の違いは、「構造体」のデフォルトが「パブリック」アクセシビリティであるのに対し、「クラス」のデフォルトはプライベートであることです。

これを理解すると、クラス内でサブタイプを定義していることがわかります。

class myclass {
private: // <- not required, you already said that by saying "class".
    struct data {
        // <-- this is a class definition with "public:" just here.
        ...
    };
};

C++ では、クラス/構造体の定義をネストできるため、たとえば、パラメーターをマーシャリングしたり値を返したりする構造体を作成できます。

class Database {
    class Result { ... };
};

...

class Exam {
    class Result { ... };
};

これら 2 つの結果クラスは、単なる「結果」ではなく、Database::Result と Exam::Result であることにより、名前空間の衝突を回避します。

ただし、これらは単なる定義です。示されているように、それらは外側のクラスには影響しません。つまり、クラスにメンバーを追加するために使用されていません。

あなたのコード:

class myclass{
private:
   struct data{  // <-- this is a TYPE declaration, struct myclass::data
       int q ;   //
       int w;    // 
   };            // <-- no member name here so does not affect myclass itself.

public:
   void get(int a, int b){
      struct data = {a , b}; // here I want to pass the variables to data struct
   }
   int max (){              // this function returns the biggest number 
      if(q>w)
         return q;
         else
            return w;
   }

};

タイプ「myclass::data」を宣言しますが、タイプ「myclass::data」のメンバーをクラスに追加しません。「struct data =」という行は不正です。TYPE に値を代入しようとしています。

おそらく次のように書かれているはずです

class MyClass {
    int m_q;
    int m_w;

public:
    void set(int q, int w) {
        m_q = q;
        m_w = w;
    }

    int max() const {
        return (m_q > m_w) ? m_q : m_w;
        // or #include <algorithm> and return std::max(m_q, m_w);
    }
};

クラスの範囲外でその構造定義を再利用する場合にのみ、 q & w を構造体に巻き上げる必要があります。たとえば、同じタイプのものをさらに追加する必要がある派生クラスまたは並列クラスで、 、おそらく次のことを行うことができますが、この正確な方法で行うと、最終的にカプセル化を破ったことで自分自身を蹴ります:

class MyClass {
public:
    struct Data {
        int m_q;
        int m_w;
    };

private:
    Data m_data;

    void set(int q, int w) {
        m_data.m_q = q;
        m_data.m_w = w;
    }

    int max() const {
        return (m_data.m_q > m_data.m_w) ? m_data.m_q : m_data.m_w;
    }
};

このメンバーの結合をある程度外部から見えるようにする必要がある場合、より良い方法は次のとおりです。

class MyClass {
public:
    class Data {
        int m_q;
        int m_w;
    public:
        Data() : m_q(0), m_w(0) {}
        Data(int q, int w) : m_q(0), m_w(0) {}

        void set(int q, int w) {
            m_q = w;
            m_w = w;
        }

        int q() const { return m_q; }
        int w() const { return m_w; }

        int max() const { return (m_q > m_w) ? m_q : m_w;
    };

private:
    Data m_data;

public:
    MyClass() : m_data() {} // or = default
    MyClass(int q, int w) : m_data(q, w) {}
    MyClass(const Data& data) : m_data(data) {}

    // Read-only access
    const Data& data() const { return m_data; }
    // To allow write access, e.g. for set:
    Data& data() { return m_data; }
};

このような単純なケースではちょっとやり過ぎですが、定型言語である C++ へようこそ。

于 2013-06-22T19:02:25.133 に答える