【问题标题】:is this possible in C++?这在 C++ 中可能吗?
【发布时间】:2009-07-07 05:21:56
【问题描述】:

从一个类创建另一个类的实例,即使我想要创建一个实例的类是在我创建实例的类的下一个声明的。就像在 C# 和 Java 中一样。

谢谢

【问题讨论】:

    标签: c++ class


    【解决方案1】:

    您可以出于某些目的使用前向声明,但无论何时实际使用它,您都需要拥有完整的类型。建议将问题更具体地说明您真正想要实现的目标,因为可能有更简单的方法来解决您的问题(如果顺序很重要,它可能表明 A 类和 B 类之间存在循环依赖关系,这通常不是好)。

    class B;
    class A
    {
    public:
       A( B b, B* bp, B& br ) : bp_(bp), br_(br) {} // ok, incomplete types can be used as argument types
       B f()
    // { return B(); } // nok: cannot create objects of incomplete type
       ;
       B* f2() { return bp_; } // ok
       B& f3() { return br_; }; // ok
       void g() 
    // { bp_->g(); br_.g(); } // nok: cannot call methods of an incomplete type
       ;
       void g( B const & b )
    // { b.g(); } // nok: cannot call methods of an incomplete type
    private:
       B * bp_; // ok (also const version)
       B & br_; // ok (also const version)
    // B b_; // nok: B must be a complete type here
    };
    class B { // A is complete, any use is correct here
       void g() {}
    };
    // From here on, B is a complete type and can be used in any possible way
    B A::f() {
       return B(); // ok, now B is complete
    }
    void A::g() {
       br_.g(); // ok, B is complete here
       bp_->g(); // ok, B is complete here
    }
    void A::g( B const & b ) {
       b.g(); 
    }
    

    【讨论】:

      【解决方案2】:

      当然。你只需要一个前向声明。像这样的东西很好用:

      #include <iostream>
      
      class B;
      
      class A {
      public:
          void hello( B &b );
          void meow();
      };
      
      class B {
      public:
          void hello( A &a );
          void woof();
      };
      
      void A::hello( B &b ) { b.woof(); }
      void A::meow() { std::cout << "Meow!" << std::endl; }
      
      void B::hello( A &a ) { a.meow(); }
      void B::woof() { std::cout << "Woof!" << std::endl; }
      
      int main() { A a; B b; a.hello( b ); b.hello( a ); return 0; }
      

      这里的关键是,在完全定义之前,您只能使用指向类的指针或引用。因此,在我给出的示例中,A 中的 hello() 方法可以声明 以获取对 B 的引用,即使此时我们还没有定义 B。但是在定义了B之后,方法A::hello()的定义就可以随意使用B了。

      【讨论】:

      • 嘿,这真的很有帮助!谢谢
      • “在完全定义之前,您只能使用指向类的指针或引用”。据我所知,您还可以在函数之间按值传递类...
      • 破译这个问题的奖励在哪里?
      【解决方案3】:

      我猜你的意思是这样做:

      class B; //Forward declaration
      
      class A
      {
        private:
         B b;
      };
      
      
      class B
      {
      
      };
      

      这在 C++ 中是不可能的,因为编译器在编译 A 类时需要知道 sizeof(B)。

      作为一种解决方案,您可以做的是:

        class B; //Forward declaration
      
              class A
              {
      
                public:
                A();
                ~A();
      
                private:
                 B* m_pB; //Store a pointer to B
      
              };
      
      
              class B
              {
      
              };
      
      A::A() 
      {
        m_pB = new B; //Create an instance of B
      }
      
      A::~A()
      {
        delete m_pB; //Explictly deallocate the memory.
        m_pB = NULL;
      }
      

      【讨论】:

      • 是的,我知道。但是如果我想访问该类的公共变量或函数怎么办?
      • 但是相反的(A 刚好在 B 之下)会编译得很好。
      • @maxx:这仍然是不可能的,因为编译器只知道使用前向声明有一个称为 B 类的东西,但它不知道它的内容。
      • @Naveen: 不对,你只需要将A的成员函数声明放在一个.cpp文件中,并#include B的声明。
      【解决方案4】:

      在标头中转发声明 B 后,您可以在 .cpp 文件中使用它,而无需麻烦地访问公共变量和方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-20
        • 1970-01-01
        • 2012-01-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多