一个类可以通过什么方式访问另一个类的成员?

Kri*_*ato 5 c++ oop design-patterns metaprogramming

早些时候,我问了一个关于如何调用静态成员的成员函数以便在实际使用静态对象之前对其进行初始化的问题。然后,我意识到我可能以错误的方式使用静态成员,这导致了这个问题:

给定一个特定的类,MyClass我们可以通过多少种方式设计我们的代码,以便MyClass能够访问另一个类的成员函数YourClass?[注意,假设一种通用情况,其中MyClass被声明MyClass.h并被定义MyClass.cpp,并且对于 也类似YourClass。]

我能想到一些,但距离专家还很远,我想你还可以举出其他几个:

包含:这可以有多种“风格”,直接包含YourClass对象是一种选择,而包含对象的指针或引用是另一种选择:

class MyClass
{
public:
  // Some MyClass members...
private:
  YourClass instance;  // or YourClass* instance / YourClass& instance;
  // Some other MyClass members...
};
Run Code Online (Sandbox Code Playgroud)

a)当然,直接包含很方便,但我可以想到一个直接的缺点:如果YourClass就内存需求而言有点大,并且您有多个MyClass实例(如我的链接问题中所示),则直接包含该对象将被淘汰的问题。此外,有一个关系并不总是有意义的。

b)在这种情况下,拥有对象的指针或引用可能更有意义。使用引用存在一个问题,即您最终可能会引用一个不再存在的对象,因此您必须确保该YourClass对象在该对象存在期间存在MyClass

c)对于指针,上述问题仍然存在,但是您可以更轻松地将指针重新分配给新对象。

继承:可以从YourClass对象继承,使得成员被继承,如:

class MyClass : public YourClass
{
public:
  // Some MyClass members...
private:
  // Some other MyClass members...
};
Run Code Online (Sandbox Code Playgroud)

a)这对于一些类来说设置起来也非常简单,但对于一般用途来说可能会变得笨拙。例如,如果 is是一个随机数生成器,那么说is-aYourClass随机数生成器不一定有意义。当然可以为随机数生成器定义一个包装类,比如调用它,然后可以继承自,这是很有意义的。MyClass RandomizableMyClassRandomizable

我个人想更多地了解静态成员、全局对象、单例的优缺点以及如何正确使用它们。那么,从“元”的角度来看,还有哪些其他方法或模式可以发挥作用呢?

附言。虽然我是从 C++ 的角度提出问题,但我想这也适用于许多其他面向对象的语言,因此不必担心给出其他语言的示例。

小智 1

有关 C++ 类成员资格访问的基础知识。

  1. 您可以访问您自己的直接类的成员(公共、受保护或私有)

    class Foo {
    public:
         int fooMember;
    };
    
    int main() {
         Foo foo;
         foo.fooMember = 1;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 您可以在子类中访问父类的 protected 和 public 成员,然后根据子类声明中的继承指示符,将父类的成员传递给 public、下一个子类或保持私有

    class Animal { 
    
    
    protected:
         int feet;
         int age;
    public:
        enum color { blue, red, green, pink } color;
    
    
     Animal(int feet) { this->feet = feet; }
     bool getFeet() { return feet; }
     void setAge(int a) { age = a; }
    
    
    };
    
    
    class Elephant: public Animal {
    
    
    public:
    
    
     Elephant(void):Animal(4) { }
     int hasFeet(void) { return (feet > 0); }
    
    
    };
    
    
    // Here you can override stuff too so:
    
    
    class Fish: protected Animal {
    public: 
            int teeth;
            enum Type { freshWater, saltWater } type;
        Fish(void):Animal(0) { }
    };
    
    
    class Mackerel: private Fish {
    
    
    public:
            Mackerel(): Fish() { teeth = 12; } /* compiles */
    };
    
    
    class SubMackerel: public Mackerel { 
    public:         
      SubMackerel() { teeth = 8; } /* does not compile teeth not accessible here */
    } ;
    
    
    int main() {
         Elephant pink;
            Fish fishy;
            Mackerel mack;
            pink.color = Animal::blue;
            // this won't compile since color is protected in Fish
            // fishy.color = green;
            fishy.type = freshWater;
            // mack.type = saltWater; // will fail
    }
    
    Run Code Online (Sandbox Code Playgroud)
    1. 最后一种方法是声明好友。友元类可以访问它作为友元的类的所有公共和私有成员。

好吧,这应该是一个开始......您可以阅读更多相关内容