在命名空间中向前声明类抛出编译器错误

时间:2013-06-22 18:03:25

标签: c++ c++11 namespaces compiler-errors forward-declaration

namespace chk{

class Car;
        Car abc()
        {
                return Car();
        }

class Car
{
        private:
                int sides;

        public:
                Car()
                {
                        std::cout<<"\ndefault called constructor";
                }
                Car(int nsides)
                {
                        std::cout<<"\ncalled constructor";
                        sides=nsides;
                }

                ~Car()
                {

                        std::cout<<"\nDeleting objext";
                }

};

       /* Car abc()
        {
                return Car();
        }*/
}

上述代码出现以下错误: -

check.cpp: In function ‘chk::Car chk::abc()’:
check.cpp:25: error: return type ‘struct chk::Car’ is incomplete
check.cpp:27: error: invalid use of incomplete type ‘struct chk::Car’
check.cpp:24: error: forward declaration of ‘struct chk::Car’


现在当取消注释下面的abc()并在abc()上方注释时,它可以正常工作。 为什么c ++不允许我在名称空间中转发声明类?

2 个答案:

答案 0 :(得分:1)

  

为什么c ++不允许我在命名空间内转发声明类?

C ++不允许的是具有诸如

之类的功能
Car abc()
{
    return Car();
}

没有类Car的定义。这是必需的,因为a)需要Car对象的大小,并且b)调用类的默认构造函数。没有类定义,就无法知道构造函数是否存在。

答案 1 :(得分:1)

问题是你的abc()函数需要Car的完整定义。

Car abc() { return Car(); }

这里要求它必须知道定义,以便它可以确定这将解析哪个构造函数。

转发声明仅涵盖您需要指针或类型引用的情况,但不包括您需要解决内部细节的情况。

确定要使用的构造函数是内部细节。此外,编译器还需要知道“Car”对象的大小,以便在按值返回时返回一个“Car”对象。

解决此问题的一种方法是转发声明函数:

class Car abc();

class Car { ... };

Car abc() { return Car(); }