【问题标题】:Right way to instantiate instance-variables in C++ [closed]在 C++ 中实例化实例变量的正确方法 [关闭]
【发布时间】:2011-10-07 20:35:42
【问题描述】:

我想问在 C++ 中哪里是实例化实例变量的正确位置?我认为它不应该在类声明中,但是除了糟糕的面向对象设计之外,我看不到任何缺点:

class A{ member m; };

我认为最好是这样:

class A{ extern member m; };

但是如果没有这样的指针我不知道如何实现它:

class A{ member* m };

A::A(){ m = new member; }

是否有“干净的解决方案”在堆栈上实现这一点(不使用指针)?

【问题讨论】:

  • 你为什么不在课堂上做呢?
  • 你想达到什么目的?
  • 你能澄清一下这个问题吗?对象内的字段与对象本身一起“实例化”。您实际上是指“类级别”还是“静态”成员?
  • 我的意思是“类级别”,但我的问题是我认为在类声明中定义了一个实例变量 - 抱歉,我的错......

标签: c++ stack instantiation instance-variables


【解决方案1】:

您可以根据需要使用构造函数初始化列表来构造所有成员变量。

A::A(const member& memberArg)
     : m(memberArg) 
{ }

查看this 了解更多信息。

【讨论】:

  • 你的意思是class A{ member m; }; 然后是member m;...A::A():m(m){}
  • 最好把参数设为const member &
  • 是的,这就是我的意思。 C++ 中的实例变量就是:class A{ member m; };
  • @Nawaz:谢谢,Nawaz...
  • 好的,谢谢,但是如果我没有来自更高级别的构造函数初始化列表的成员对象怎么办 - 是否有机会在 A 类中执行此操作(没有新/指针)?
【解决方案2】:

您想使用成员初始化器:它们是初始化具有需要参数的构造函数的类成员的唯一方法,也是初始化其他类成员的最干净的方法。

如果你有类 A 和一个带有构造函数的成员 m:

class A { member m; }

你想要

class A { member m; A(); }

A::A()
: m(<constructor params>)
{
}

【讨论】:

    【解决方案3】:

    您可以在 .h 文件中声明您的实例变量:

    啊.h

    class A {
    
       public:
          A();
       private:
          int value;
          double someOtherValue;
    }
    

    您可以像这样在 .cpp 文件中实例化它们:

    A.cpp

    A::A(): value(5), someOtherValue(10.0)
    {
       ...
    }
    

    【讨论】:

      【解决方案4】:

      如果成员对象完全由封闭的A 对象控制,那么您的第一个示例是正确的方法。它确实有一个缺点,即在定义 A 时需要完整定义 member

      您可以查看pimpl idiom 以减少耦合,但这仍然需要对象是基于堆而不是基于堆栈的。

      【讨论】:

        【解决方案5】:

        我认为您对如何实例化对象存在误解。如果您所做的只是声明一个类,则实际上不会实例化任何成员变量。直到你构造了那个类的实例,它的成员变量才存在。

        这是一个显示成员对象何时被实例化的示例:

        class ClassA
        {
        public:
          ClassA() { std::cout << "Hello!\n"; }
        };
        
        class ClassB
        {
        public:
          ClassA objA;
        };
        
        int main()
        {
          // do some work
          ClassB objB; // here, a ClassB object is created, and with it its member ClassA object, so "Hello!" is printed
          return 0;
        }
        

        至于如果 ClassA 的构造函数需要参数,您具体如何指定创建哪种类型的 ClassA 对象,其他答案很好地解释了它。

        【讨论】:

        • 谢谢肖恩,你是对的,我对 C++ 中的对象是如何实例化的有一个误解。
        【解决方案6】:

        我认为它不应该在类声明中,但除了糟糕的面向对象设计之外,我没有看到任何缺点:

        class A{ member m; };

        您认为这种糟糕的面向对象设计的原因是什么?这是 C++ 中的首选机制。

        我觉得最好是这样:

        class A{ extern member m; };

        这不是有效的代码。使用 extern 等存储类规范限定成员数据是非法的。

        但是如果没有这样的指针我不知道如何实现它:

        class A{ member* m; };
        A::A(){ m = new member; }

        这会起作用,但为什么要这样做呢?在我看来,您正试图将 Java POV 导入 C++。一切都是分配的,一切都是Java中的引用。在许多(大多数!)情况下,没有理由在 C++ 中分配数据成员。它所做的只是添加一个不需要的间接并添加一个内存可能泄漏的地方。

        【讨论】:

          猜你喜欢
          • 2012-12-20
          • 2010-11-02
          • 1970-01-01
          • 1970-01-01
          • 2020-04-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多