如何在 C++ 中以更少的空间定义类字段/方法

Posted

技术标签:

【中文标题】如何在 C++ 中以更少的空间定义类字段/方法【英文标题】:How can I define the class fields/methods in less space in C++ 【发布时间】:2012-01-31 09:44:40 【问题描述】:

这是我的标题:

#ifndef MYCLASSES_H_
#define MYCLASSES_H_

#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))

namespace mynamespace 

class A

    class B
    
        class C
        
            void doStuff(B *pB);
        

        static const C SOME_ARRAY[];
        static const int SOME_ARRAY_COUNT;
    


 //namespace mynamespace
#endif /* MYCLASSES_H_ */

这就是 CPP:

#include "myclasses.h"

namespace mynamespace 

void A::B::C::doStuff(A::B *pB)

    /* ... */


const A::B::C A::B::SOME_ARRAY[] = 
    /*...*/
;

const A::B::SOME_ARRAY_COUNT = ARRAY_SIZE(

 //namespace mynamespace

我应该怎么做才能使 .CPP 文件中的定义具有更短的名称?实在是太麻烦了。

【问题讨论】:

你真的需要3个内部类吗?只使用继承不是更好吗? 男人走进医生。他说“医生,当我把它撞到墙上时,我的头很痛”。医生说:“不要把头撞到墙上,你的头就不会痛了”。由于 B 和 C 位于 A 级的私人部分,因此世界无法看到它们。因此,无需将它们嵌套在 A 中,只需使它们对外界不可见。最简单的方法是将它们放在源文件内的匿名命名空间中。 @LokiAstari 我正要写那个。顺便说一句,“将评论转换为答案”按钮在哪里? ;) 你不应该真正使用那个数组大小的宏,当 x 是一个指针时它会失败(或者会突然衰减为一个)。使用 `template size_t array_size(T(&) [N] ) return N; ` 在没有传递实际数组时会出错。 您不应该使用保留名称作为包含守卫,否则this 可能会发生。 【参考方案1】:

男人走进医生。他说“医生,当我把它撞到墙上时,我的头很痛”。医生说:“不要把头撞到墙上,你的头就不会痛了。”

由于 B 和 C 位于 A 类的私有部分,因此世界无法看到它们。

因此无需将它们嵌套在 A 中,只需使它们对外界不可见。 执行此操作的简单方法是将它们放在源文件内的匿名命名空间中。

#ifndef MYCLASSES_H_
#define MYCLASSES_H_

#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))

namespace mynamespace 

class A



 //namespace mynamespace
#endif /* MYCLASSES_H_ */

这就是 CPP:

#include "myclasses.h"


namespace

    // This is an anonymouse namespace
    // It does not export it symbols outside the compilation unit.
    // So only A should be able to see them
    class B
    
            static const C SOME_ARRAY[];
            static const int SOME_ARRAY_COUNT;
    ;
    class C
    
            void doStuff(B *pB);
    ;

void C::doStuff(B *pB)

    /* ... */


const C B::SOME_ARRAY[] = 
    /*...*/
;

const B::SOME_ARRAY_COUNT = ARRAY_SIZE(

【讨论】:

谢谢。非常感谢您的努力:-)【参考方案2】:

可以尝试使用 using 声明:

using A::B;

【讨论】:

这仅适用于命名空间范围内的名称;这些都在一个类范围内。【参考方案3】:

typedefs 让你缩短命名:

#include "MYCLASSES.h"

namespace mynamespace 

typedef A::B b;
typedef b::C c;

void c::doStuff(b *pB)

    /* ... */


const c b::SOME_ARRAY[100] = 
    /*...*/
;

const int b::SOME_ARRAY_COUNT = ARRAY_SIZE(SOME_ARRAY);

 //namespace mynamespace

【讨论】:

【参考方案4】:

很遗憾,你不能。这只是 C++ 的一个语法属性。

因此,您应该更喜欢 C++ 中的平面嵌套层次结构:不要无休止地嵌套类,将它们放在同一个上层命名空间中。在其他语言中,这是一个很大的禁忌,因为它会将实现细节泄露给公共接口。1

在 C++ 中并非如此,因为这里有不同的编译单元来强制封装和信息隐藏。所以扁平的层次结构实际上在大多数情况下都很好。


1 但即使在其他语言中,三个嵌套类也在挑战极限。

【讨论】:

【参考方案5】:

没有干净的方法可以做到这一点。如果是嵌套命名空间,可以使用usingnamespace aliasing

既然是类,我能想到的最好的就是:

#define B A::B
#define C B::C

但它绝对不干净。我不会这样做的。

【讨论】:

【参考方案6】:

除了类似这样的事情之外,没有其他真正的方法可以做到这一点:

    #define AB mynamespace::A::B;

允许这样做:

    mynamespace::A::B::C myobj;

请注意,许多程序员(包括我自己)认为这是不好的做法,因为 AB 是什么并不明显。

变成:

    AB::C myobj;

您不能对类使用“使用”,只能对命名空间使用。所以在cpp文件中你可以这样做:

    using mynamespace;
    A::B::C myobj;

但不是:

    using mynamespace::A::B;
    C myobj;

一般来说,许多人都同意最佳做法是完全限定名称。

【讨论】:

【参考方案7】:

或者,您可以在头文件中编写实现。不过,这是一种非常糟糕的做法。

【讨论】:

以上是关于如何在 C++ 中以更少的空间定义类字段/方法的主要内容,如果未能解决你的问题,请参考以下文章

以更少的电池消耗获取连续的位置变化

在 Xcode 中使用 MLModel 时如何重写更少的代码

用更少的内存在 C++ 中实现二维数组

如何写更少的 if else

更少的颜色混合[重复]

算法--02---时间空间复杂度