这在 C++ 中可能吗?

Posted

技术标签:

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

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

谢谢

【问题讨论】:

【参考方案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 文件中使用它,而无需麻烦地访问公共变量和方法。

【讨论】:

以上是关于这在 C++ 中可能吗?的主要内容,如果未能解决你的问题,请参考以下文章

一个具有多个可接受值的变量。这在Lua中可能吗?

c++实例化一个对象

这在 TestFlight 中可行吗?

在 C++ 中使用默认参数跳过模板参数真的不可能吗,为啥语法建议不这样?

在 C 回调中在 C++ 中引发异常,可能跨越动态库边界......它安全吗?

C++:监控文件大小。这可能有问题吗?