当前位置:  开发笔记 > 编程语言 > 正文

基准的前瞻性声明

如何解决《基准的前瞻性声明》经验,为你挑选了2个好方法。

我正在尝试创建正确的头文件,其中不包含太多其他文件以保持其清洁并加快编译时间.

这样做时遇到两个问题:

    基类的前向声明不起作用.

    class B;
    
    class A : public B
    {
    
        // ...
    }
    

    关于STD类的前向声明不起作用.

    namespace std
    {
        class string;
    }
    
    class A
    {
        string aStringToTest;
    }
    

我该如何解决这些问题?



1> Daniel Earwi..:

你无法解决的第一个问题.

第二个问题与标准库类无关.这是因为您将类的实例声明为您自己的类的成员.

这两个问题都是由于要求编译器必须能够从其定义中找出类的总大小.

但是,编译器可以计算出指向类的指针的大小,即使它还没有完整的定义.因此,在这种情况下,可能的解决方案是在消费类中使用指针(或引用)成员.

在基类案例中帮助不大,因为你不会得到'是'关系'.

也不值得这样做std::string.首先,它应该是一个方便的字符缓冲区包装器,以避免对这么简单的事情进行内存管理.如果你拿着一个指向它的指针,只是为了避免包含标题,你可能会把一个好主意放得太远.

其次(正如评论中所指出的)std::string是一个typedef std::basic_string.因此,您需要转发声明(然后使用),而这时候事情变得非常模糊和难以阅读,这是另一种成本.是不是真的值得吗?


@Shmoopty:准确地说,它无法向前声明,因为标准中未定义模板参数的数量.实现可以将其他模板参数添加到该语言所需的参数.
实际上TomWij即使使用字符串指针或引用也会遇到问题.他错误地假设std :: string是一个类,它不是.它是模板basic_string <>的typedef,并且根本无法进行前向声明.
即使你能够正确地完成这些事情,命名空间std中的声明(除了标准头中模板的特化)也是未定义的行为.简而言之,你可以从std转发声明的东西,它经常有用,但你不应该因为它没有定义工作.

2> David Rodríg..:

正如Earwicker之前所回答的那样,在任何情况下都不能使用前向声明,因为编译器需要知道类的大小.

您只能在一组操作中使用前向声明:

声明将前向声明的类作为参数或返回它的函数

声明成员指针或对前向声明的类的引用

在类定义中声明前向声明类型的静态变量

你不能用它

声明给定类型的成员属性(编译器需要大小)

定义或创建该类型的对象或删除它

调用类的任何静态或成员方法或访问任何成员或静态属性

(我忘了吗?)

请注意声明a auto_ptr与声明原始指针不同,因为auto_ptr实例化将在超出范围时尝试删除指针,并且删除需要完整声明类型.如果使用auto_ptrin来保存前向声明的类型,则必须提供析构函数(即使为空)并在看到完整的类声明后定义它.

还有其他一些细微之处.当你转发声明一个类时,你告诉编译器它将是一个类.这意味着它不能是一种enumtypedef另一种类型.当您尝试转发声明时std::string,这是您遇到的问题,因为它是模板的特定实例化的typedef:

typedef basic_string string; // aproximate

要转发声明字符串,您需要转发声明basic_string模板然后创建typedef.问题是标准没有说明basic_string模板所采用的参数数量,它只是声明如果它需要多个参数,那么其余参数必须具有默认类型,以便上面的表达式编译.这意味着没有标准的方式来转发声明模板.

另一方面,如果你想要转发声明非标准模板(非STL,那就是),只要你知道参数的数量就可以这样做:

template  class Test; // correct
//template  class Test; // incorrect even if U has a default type

template  class Test {
   // ...
};

最后,Roddy给你的建议:尽可能多地向前宣布,但是假设必须包含一些东西.

推荐阅读
oDavid_仔o_880
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有