所以,正如我们所有人都希望的那样,在面向对象编程时,当你需要以某种方式访问另一个类的方法中的类的实例时,你转向通过该实例参数。
我很好奇,在传递一个对象或指向该对象的指针时,良好做法/不易破坏事物的区别是什么?
答案 0 :(得分:8)
养成通过引用传递对象的习惯。
void DoStuff(const vector<int>& values)
如果您需要修改原始对象,请省略const
限定符。
void DoStuff(vector<int>& values)
如果您希望能够接受空/无答案,请通过指针传递。
void DoStuff(vector<int>* values)
如果您想对本地副本执行操作,请按值传递。
void DoStuff(vector<int> values)
当您引入大量并发时,问题才会真正出现。到那个时候,你将知道何时不使用某些传递技术。
答案 1 :(得分:1)
我选择const
引用作为默认值。当然,非const
如果必须为客户端改变对象。很少需要偏离使用引用。
指针不是很像C ++,因为引用可用。引用很好,因为它们被禁止引用任何内容。 更新:为了澄清,首选适用于类型和数组的容器,但对于某些内部实现,您需要传递指针。
对象/值在语义上完全不同。如果我需要副本,我通常只需要在需要的函数内创建它:
void method(const std::string& str) {
std::string myCopy(str);
...
答案 2 :(得分:1)
如果您希望能够指示不存在(通过传递NULL),则将指针传递给对象。
尽量不要传递对象的值,因为它调用复制构造函数来在调用函数的范围内创建对象的本地版本。相反,通过引用传递。但是,这里有两种模式。为了获得完全相同的有效行为传递值(不可变“副本”)而没有开销,通过const引用。如果您觉得需要更改传递的对象,请传递(非常量)引用。
答案 3 :(得分:0)
实际上,将指针传递给对象的确没有充分的理由,除非你想以某种方式表明没有对象存在。
如果要更改对象,请传递对象的引用。如果要保护它不受函数内的更改影响,请按值或至少const引用传递它。
有些人通过参考传递速度改进(仅传递大型结构的地址而不是结构本身),但我不同意。在大多数情况下,我更喜欢我的软件比快速安全,这是一个说法的必然结果:“你不能得到比错误更优化的东西。”: - )
答案 4 :(得分:0)
实际上你可以传递给方法的是指向对象的指针,对象的引用和对象的副本,所有这些也可以是常量。根据您的需求,您应该选择最适合您需求的产品。
你可以做的第一个决定是你传递的东西是否应该能够改变你的方法。如果你不打算改变它,那么const引用可能是最好的选择(通过不改变我也意味着你不打算调用该对象的任何非const方法)。有什么好处?您安全地编译对象以及方法签名本身会说“我不会更改该参数”。
如果必须更改此对象,则可以传递引用或指针。选择其中一个选项并不是必须的,所以你可以选择其中一个。我能想到的唯一区别是指针可以是NULL(即根本不指向任何对象),而引用总是指向一个存在的对象。
如果您的方法中需要的是对象的副本,那么您应该传递对象的副本(不是引用而不是指针)。例如,如果您的方法看起来像
void Foo(const A& a) {
A temp = a;
}
然后,这清楚表明传递副本是更好的选择。
希望这会让事情变得更加清晰。
答案 5 :(得分:0)
面向对象编程是关于多态,Liskov替换原则,旧代码调用新代码,你可以命名它。将具体(派生)对象传递给适用于更抽象(基础)对象的例程。如果你不这样做,你就不会做OOP。
只有在传递引用或指针时才能实现。通过值传递最好保留,嗯,值。
区分值和对象很有用。值总是具体的,没有多态性。它们通常是不可改变的。 5是5,“abc”是“abc”。您可以通过(const)引用按值或传递它们。
对象在某种程度上总是抽象的。给定一个对象,人们几乎总能将其细化为更具体的对象。 RectangularArea可以是一个Drawable,它可以是一个可以是ToplevelWindow的Window,它可以是一个ManagedWindow,它可以是......这些必须通过引用传递。
指针是完全独立的蠕虫。根据我的经验,最好避免使用裸指针。使用不能为NULL的智能指针 。如果您需要可选参数,请使用明确的optional
类模板,例如boost::optional
。