2013-04-12 67 views
-1

考虑这个类。班级成员总是作为一致性的指针?

#pragma once 

#include <memory> 
#include <string> 

class A; 
class B; 

class Test 
{ 
public: 
    Test(); 
    ~Test(); 

private: 
    std::unique_ptr<A> m_a; 
    std::unique_ptr<B> m_b; 
    std::unique_ptr<std::string> m_string1; // 1 
    std::string m_string2; // 2 
}; 

我总是尝试在头文件中转发声明类。但是,我不会那样做标准头文件,向前声明模板类的typedef只是很痛苦。无论如何,如果我有标题可用 - 我应该更喜欢第一种方式还是第二种方式 - m_string1m_string2?我觉得如果我混合使用指针和值类型,那么它看起来不一致。把所有东西都作为指针是一个好主意吗?

+0

此问题属于http://www.codereview.stackexchange.com/。 – antonijn

+0

我认为使用指向每个成员的指针可能会导致额外的空间 - 指针在64位系统中需要32位和8字节中的4个字节。简单的数据类型可以更好地存储为值。 – cppcoder

+0

@cppcoder:它可能是对齐使短类型被存储到相同的长空间......很难说何时(而不是)这是真的。 –

回答

1

std::string已经拥有了一个动态结构(所以它本身是一个指针)

毕竟,如果你考虑一个字符串“不透明类型”这样不透明的,你甚至不想包含它的头,同样的应该也是unique_ptr ...但是你必须迟早停止,否则你最终会得到一类普通的指针,而大五(ctor,dtor,copy,assign,move,transfer)都是重新定义的。但是这是每次都重新实现智能指针。

另外考虑到将一个类拆分成过小的动态“细节”会将对象扩展到内存中,从而不能根据系统缓存对任何处理器进行优化(或使其更难)。

如果你有一些模板,那么pimpl成语甚至变得毫无用处:你必须将整个类作为头部公开。

在我看来,你只是太深入这个成语的应用。

0

你想让它分配在堆上还是堆栈中?有理由使用每种方法(例如对象的生命周期),为情况使用适当的选择。如果你不需要,我觉得指针管理没有意义;即使你使用智能指针。

此外,像std::string这样的类在内部通常是指向堆分配字符串的指针。所以在这种情况下,你会为​​一个指针做堆分配。堆分配比堆栈分配更昂贵,并且大量非常小的分配将趋向于快速地分割堆空间,使得分配器难以找到相邻空闲空间的合理大小的块(比较慢)(a.k.a.较慢)。

国际海事组织,一般性的一致性是好的,但为了一致性的一致性是僵化和不切实际的。

1

如果你要做到这一点,改用pImpl

class TestImpl; 
class Test 
{ 
public: 
    Test(); 
    ~Test(); 

private: 
    std::unique_ptr<TestImpl> m_; 
}; 

和您的.cpp文件中,创建一个与它的所有数据TestImpl那里。

这会更好地隐藏您的实现细节,并减少间接性,因为如果仍然删除了一个间接步骤,则Test的所有数据现在都是连贯的(成簇的)。