在c++中返回对象的最佳方式
Best way to return an object in c++?
当谈到c++时,我很笨,返回对象的更好方法是什么?我来自脚本世界,对象总是引用,我试图实现相同的概念…我的基础是什么时候通过引用传递,什么时候在c++中通过指针传递?,其中一位用户说:"一条很好的经验法则是:‘尽可能使用引用,必要时使用指针。’"
// basic layer class
class Layer { private: Channel channel; // NEVER NULL };
// return object by pointer
Channel *Layer::getChannel() {
return &channel;
};
// return by reference
Channel& Layer::getChannel() {
return channel;
};
第二个版本的问题是编译器会接受这一行:
Channel channel = layer.getChannel(); // creates a copy BAD
Channel &channel = layer.getChannel(); // reference good
是否有办法强制第二个选项的调用者不创建新通道,或者第一个选项更好,即使它永远不会为NULL?
您需要调整Channel
类本身,使其不可复制。如果它是可复制的,用户可以复制它,你做什么都不能阻止它。
如果复制不是一个有意义的操作,那么你可以"禁用"它。只需将复制构造函数(Channel(const Channel&)
)和赋值操作符(Channel& operator=(const Channel&)
)定义为私有。那么,任何复制该类的尝试都将导致编译错误。
顺便说一句,正如其他人提到的,c++不是您熟悉的脚本语言。一切都不是一个参考,如果你假装不是,你只会让自己陷入一个痛苦的世界。在c++中,通常在堆栈上分配对象,并按值传递对象,而不是传递引用和指针。
返回引用(或const引用)是getter方法让调用者直接访问成员变量的正常方式,因此我建议使用getChannel()
的第二个版本。
如果你想防止调用者不适当地复制Channel
,你可以通过将它的复制构造函数设为私有来实现。(如果你想防止所有元素复制,甚至Channel
本身,你可以声明构造函数private,然后不实现它。)但是,只有在复制实际上是无意义的情况下才应该这样做,例如,如果类代表某种无法复制的底层资源。不要因为你认为调用者不应该需要就禁止复制;这是来电者的决定。
返回对象本身的副本,如果复制对您的目的来说并不昂贵,并且您不需要能够更改原始对象。这应该是默认值。
Channel Layer::getChannel() { return channel; };
以引用或指针方式返回,当复制开销较大或您可能想要更改值时。通过引用返回允许你做这样的事情:
layer.getChannel().clear();
让它作用于那个层的通道
返回一个指针类似于返回一个引用,除了它给了你更多的灵活性,因为指针可以不指向任何对象。当我想在另一个类中使用存储"通道"时,我经常使用指针。然后我要写
class MyClass
{
// ...
void setChannel(Channel *pC) { m_pChannel = pC; }
private:
Channel * m_pChannel; // pointer to a channel that came from layer
}
既然你返回了对对象的引用,你就给了类的用户直接访问对象的权限,如果你要这样做,为什么要把对象设为私有呢?
即使使用指针返回版本,也不能阻止调用者创建新实例。
Channel* channel = new Channel(*layer.getChannel());
我知道有办法达到这个目标。(例如,将channel的actor设为私有,这样只有它的静态成员函数或友元函数才能创建它。)但是,我认为这不是你问题的重点。
关键是,当你让成员函数返回引用或指针时,你给调用者提供了选择的选项,他可以选择是复制还是引用。此外,您可以通过添加const
使其为只读,从而使您的意图更加明确。
对于您的情况,我将使用reference-return-version,因为Channel不能为空。如果不希望他们更改成员变量,则返回const引用。记住,没有确定返回值类型的唯一最佳方法,因为它取决于您想要表达的内容。希望能有所帮助!:)
最重要的是保持你周围代码的可读性。"入乡随俗"很重要。你只写一次,但是每个维护你代码的人都要读它。如果突然之间,你的代码遵循的指导方针与你周围的人不同,这意味着他们需要首先弄清楚你的风格,然后弄清楚你在做什么……
我所见过的一种非常有效的方法是使用指针来表示更改的内容,使用const引用来表示不更改的内容:
class Passenger {
...
};
class Car {
public:
int speed() const { return speed_; }
void set_speed(int speed) { speed_ = speed; }
const Passenger& passenger() const { return pass_;}
Passenger* mutable_passenger() { return &pass_; }
private:
int speed_;
Passenger pass_;
};
这个类的客户端可以做:
const Passenger& pass = car.passenger(); // no copy, but don't need to deal with NULL ptrs.
其他建议复制编译错误的答案是好的
- 在c代码之间共享数据的最佳方式
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 如果条件为TRUE(最佳方式?),则在do while循环中后置增量
- 在reactor中存储eventHandlers的最佳方式是什么
- 在AVX通道中混洗的最佳方式
- 从 T 创建 std::future 的最佳方式<T>
- C++:使用 std::unique_ptr 访问重载运算符++的最佳方式?
- 对列表列表中的元素进行分组的最佳方式
- 利用 GPU 的最佳方式
- 使用 QT C++过滤大数据的最佳方式
- 算法设计:用边界数字表示 2D 网格的最佳方式,以C++?
- 在C++中共享键值对的最佳方式
- 为Catch2中的外部文本文件指定路径的最佳方式
- 代表Quarto棋盘游戏棋子的最佳方式
- 等待线程的最佳方式是什么
- 将uint8_t*buffer和size_tbufferlen从C++传递到C中的API函数的最佳方式是什么
- 创建控制台菜单C++的最佳方式
- 只显示片段着色器的最佳方式是什么
- 复制文件的最佳方式是什么,以便我可以在复制过程中轻松取消复制?