效率vs封装:孰优孰劣
Efficiency vs Encapsulation: Which is preferred?
在类中实现良好的封装将确保没有外部力量可以修改对象的内部。在c++中,这意味着类应该自己分配所有需要动态分配的对象。如果必须对这样的对象进行复制,则意味着也必须复制许多内部属性(不仅仅是指针)。这可能会导致某些程序的大量开销。下面是一个例子:
class A { };
class B : public A {
private:
std::vector< const A* > m_children;
public:
B( ) : m_children( 0 ) { }
B( const B& src ) : m_children( src.m_children.size( ) ) { // Make it a copy of src
for ( unsigned int i = 0; i < m_children.size( ); i++ )
// Make a full copy of src element (and all children, not implemented here)
m_children[ i ] = copyOf( *src.m_children[ i ] ); // Dynamically allocates copy!
}
~B( ){ // Deallocate all children
while ( !m_children.empty( ) ){
delete m_children.back( ); // Get last element in array
m_children.pop_back( ); // Remove last element
}
}
void addChild( const B& child ) {
m_children.push_back( new B( child ) ); // Notice dynamic allocation
}
};
B build( int x ) {
B b;
if ( x != 0 ) b.addChild( build( x - 1 ) );
return b;
}
int main( int argc, char **argv ) {
B b = build( 10 ); // Make 10 generations with 1 child each
}
每次将子节点添加到B时,它将再次被完全分配(包括它的所有子节点)。这确实提供了良好的封装,因为无论在什么情况下,父指针都是唯一可以实际修改其子指针(或释放指针)的对象。此外,它对在自身毁灭时删除这些儿童负有全部责任。这在内存管理方面不是很有效。对于每个build()函数,必须动态地创建和删除大量附加对象。
为什么有两种可能性:
要么我在这里遗漏了什么,这可以通过实现良好的封装和效率来完成。如果是这样,请告诉我。
或者,这是唯一的方法,然后:哪种方法通常是首选的;强封装(没有外部访问),或在类外部分配对象,以便内存操作发生较少,但"外部世界"可以访问这些指针及其对象(这是不太安全的)?
应该使用move语义来避免不必要的复制。你需要给class B
添加一个move构造函数。
class B
{
B(B&& rhs)
{
std::swap(m_children, rhs.m_children);
}
}
然后您可以将addChild()
函数更改为:
class B
{
void addChild(B child)
{
m_children.push_back( new B( std::move(child) ) );
}
}
为什么会这样?在build()
函数中,您将临时传递给addChild()
函数。这将调用move构造函数,然后继续移动对象。
LIVE DEMO -删除复制构造函数,因此您可以看到没有复制。
相关文章:
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 数据成员SFINAE的C++17测试:gcc vs clang
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 正在VS调试器中监视映射条目
- Confusion: decltype vs std::function
- 将IBM Rhapsody模型集成到VS 2019中
- VS Code "command":"make"与终端窗口中的命令行"make"不同
- 使用VS Code和CMake Tools运行自定义命令
- 修改 VS Code 中的默认C++代码段
- 如何使用c++在VS 2019上运行SQL查询
- vs 2015 constexpr变量不恒定,但与2019相比还好吗
- 完美前进使用 std::forward vs RefRefCast
- 将可变参数函数的参数封装在类实例中
- 从VS 2015更新3更新到VS2015更新3 d后浮点计算行为不同的原因
- 如何封装一个函数,以便它只能由同一类中的一个其他函数调用?
- VS 2015 链接错误 无法构建依赖于 libcurl 的项目
- 效率vs封装:孰优孰劣