3

为什么 A 和 B 类的前向声明不起作用?

#include <iostream>
using namespace std;

class A, B;    

class A {
public:
    A() {
        new B();
    }
};

class B {
public:
    B() {
        new A();
    }
};

int main () {
    A a = new A();
    B b = new B();
};

编译器错误:

classes.cpp:4:8: error: expected unqualified-id before ‘,’ token
classes.cpp:4:10: error: aggregate ‘A B’ has incomplete type and cannot be defined
classes.cpp: In constructor ‘A::A()’:
classes.cpp:9:7: error: expected type-specifier before ‘B’
classes.cpp:9:7: error: expected ‘;’ before ‘B’
classes.cpp: In function ‘int main()’:
classes.cpp:22:14: error: conversion from ‘A*’ to non-scalar type ‘A’ requested
classes.cpp:23:4: error: expected ‘;’ before ‘b’
4

3 回答 3

5

像这样:

class A
{
public:
    A();
};

class B
{
public:
    B();
};

A::A() { new B(); }    // terrible code, leaks, serves no purpose
B::B() { new A(); }    // likewise
于 2013-04-01T16:44:04.730 回答
1

当您需要创建对象时,前向声明不起作用。

前向声明创建了一个不完整的类型。您不能使用它来声明成员或基类,因为编译器需要知道类型的布局。您不能定义将类型作为参数(按值)或返回(按值)的函数。

前向声明类型可以做什么。

  1. 您可以声明指向前向声明类型的指针或引用。
  2. 定义具有类型的指针/引用作为参数的函数
  3. 定义返回类型的指针/引用的函数
  4. 您可以原型化一个接受类型作为参数的函数
  5. 您可以对返回类型的函数进行原型设计。

顺便说一句,您正在尝试做的事情将导致无限递归。

创建 A 的对象 -> A 的构造函数将创建 B 的对象 -> B 的构造函数将创建 A 的对象 -> A 的构造函数将创建 B 的对象,依此类推,直到你的程序崩溃。

于 2013-04-01T16:46:13.157 回答
1

如果要创建对象,编译器必须知道定义。前向声明产生不完整的类型。您仅使用前向声明来声明参数(声明函数或原型)或返回指针或引用的类型。您可以只声明构造函数并在已知对象定义时定义它们,如下所示:

class Aa {
public:
    Aa();
};

class Bb {
public:
    Bb();
};

Aa::Aa(){
    new Bb;//do something
}
Bb::Bb(){
    new Aa;//do something
} 

顺便说一句:小心无限分配堆栈溢出......

于 2013-04-01T16:53:01.617 回答