我举了下面的例子来说明我的问题。假设Abc
是一个将使用另一个类(Def
)的类。假设Def
是一个包含许多类成员的大类(复制代价很高),让指向Def对象的指针成为Abc类的一部分更有意义。然后在实现Abc
类函数do1
时,它可以通过其指针pDef
引用Def对象。
class Abc
{
public:
Abc(Def &def)
{
pDef = &def;
}
~Abc()
{
}
void do1();
private:
Def *pDef;
}
但是,如果我以这种方式实现类Abc,我将面临Def
指针可能无效的风险。关于改进这个班级设计的任何想法?我的一个想法是使用共享指针:
class Abc
{
public:
Abc(boost::shared_ptr<Def> def)
{
pDef = def;
}
~Abc()
{
}
void do1();
private:
boost::shared_ptr<Def> pDef;
}
编辑:我想说明我的主要目的是在构建类Abc
时避免昂贵的复制操作。对我来说,使用共享指针和James Adkison的解决方案(接受的答案)都可以解决问题。但是对昂贵的Def
对象的影响可能会有所不同。使用共享指针将保留对象的许多副本,而使用James Adkison的解决方案只保留Def
对象的一个副本。
答案 0 :(得分:3)
假设Def是一个包含许多类成员的大型类
我认为这意味着复制def split_key(k):
if '#' in k:
return k.split('#')[0]
else:
return k
def group_keys(keys):
for K, G in groupby(keys, key=split_key):
yield split_key(K), sum(1 for g in G)
def slice_row(mapping, row):
i = 0
for key, length in group_keys(mapping):
if length == 1:
yield key, row[i]
else:
yield key, row[i:i + length]
i += length
print(dict(slice_row(mapping, row[0])))
# >>> {'key4': 'val4', 'key6': ['val9', 'val10'], 'key5': ['val5', 'val6', 'val7', 'val8'], 'key3': 'val3', 'key1': 'val1', 'key2': 'val2'}
类的成本很高。但是,使用C ++ 11,您可以为Def
实现移动语义,并使Def
实现简单有效。
注意:此答案基于以下假设:问题使用任何指针(智能或其他)的唯一原因是避免昂贵的副本。
Abc
现在class Def
{
public:
Def() {}
Def(const Def& other) { /* ... */ } // Copy constructor even though it's expensive
Def(Def&& other) { /* ... */ } // Move constructor for efficiency
Def& operator=(const Def& other) { /* ... */ } // Copy assignment
Def& operator=(Def&& other) { /* ... */ } // Move assignment
};
类支持复制语义,即使复制类可能很昂贵。但是,它还支持移动语义,以便在不需要副本时有效使用。
Def
如果用例实际上支持共享所有权语义,我只提倡使用class Abc
{
public:
Abc() {}
Abc(const Def& def) : mDef(def) {} // Perform an expensive copy
Abc(Def&& def) : mDef(std::move(def)) {} // Perform a move
// Implement any other member functions which could accept Def
// via copy or move
private:
Def mDef;
};
。
答案 1 :(得分:1)
如果可以使用引用,为什么要使用指针?
class Abc
{
public:
Abc(Def &def) : pDef(def)
{
}
void do1();
private:
Def& pDef;
}
你没有通过所有权,因此不需要指针。
将引用想象为一个永远不能为null的指针。
答案 2 :(得分:0)
这是std::shared_ptr
的用途。如果使用std::shared_ptr
,指针将始终有效(只要遵循所有非常简单的规则)。