我可以制作一个对象方法,如果单独调用,它将自行修改,但如果在复制初始化期间调用,则会返回一个新对象?
Can I make an object method that will modify itself if called alone but return a new object if called during copy initialization?
我正在编写一个自定义日期时间类。是否可以做这样的事情:
datetime mydate;
mydate.to_utc(); // object modifies itself
但是当这样称呼时:
datetime mynewdate = mydate.to_utc();
或者像这样:
datetime mynewdate(mydate.to_utc());
我不希望 mydate.to_utc() 修改自己,只是用 mydate.to_utc() 的值初始化/构造 mynewdate;
谢谢
我通常最终要做的是提供两个功能:
struct datetime
{
// mutate the object itself
void apply_to_utc();
// return the new object
auto to_utc() const -> datetime;
};
这使得调用哪个函数以及调用者的意图更加清晰。
虽然我同意其他人的观点,即混合这样的 API 通常是一个坏主意,但无论如何都有一个简单的方法可以解决它:使非返回函数不返回任何内容(当然),并使返回函数const
限定的。成员函数const
限定是函数签名的一部分,可用于区分重载。
像这样:
class datetime
{
public:
// ...
// This function modifies the current object in place
void to_utc();
// This function returns a new datetime object
datetime to_utc() const;
};
与上述类似的代码对于"setters"和">getters"来说并不少见,但是编译器还能够通过参数区分"setter"和"getter"("setter"有参数,"getter"没有)。
"setters"和">getters"与上述代码之间的区别(如前所述)编译器可以通过参数区分"setter"和"getter"。这与我上面对所问问题的解决方案无关。并可能导致构建错误,如评论中所述。提供的解决方案在某些情况下可能有效,但在其他情况下则无效,因此使用时应小心。
你打算实现的东西是不可能用C++的方法实现的:重载分辨率完全独立于返回类型 - 以及是否被评估的返回类型。
所以这两个不同的重载
void to_utc(); // self-modifying
datetime to_utc(); // returning new object
将永远保持模棱两可。
现在你可以尝试通过让其中一个 const 来区分它们(正如一些程序员家伙所建议的那样),但这不会产生你所追求的效果:
datetime dt0;
datetime dt1 = dt0.to_utc();
dt0
不是常量,因此重载分辨率也会选择非常量重载,您最终会再次修改自身dt0
。更糟糕的是:当选定的重载返回void
时,代码甚至无法编译。现在,您可以通过适当地强制转换来解决此问题:
datetime dt1 = const_cast<datetime const>(dt0).to_utc();
不过,我有一些怀疑,如果这还只是问题的意义......
实际上剩下的是重命名两个重载之一:
void to_utc(); // self-modifying
datetime as_utc() const; // creating a copy
// ^^^^^
// independent from given problem: the function won't modify 'this' object
// so having it const still is a good idea...
或者您将其中一个重载作为独立式(或静态;不过,我更喜欢前者)功能,例如 :
datetime to_utc();
void to_utc(datetime&);
不过,我个人会保留两个名称不同的成员函数......
- 如果 std::vector::clear() 不是静态的,如何在没有实例的情况下调用它?
- 如果整个应用程序是虚拟映射的,为什么 new 会进行系统调用?
- join() 失败,如果在线程内部调用 io_context.run()
- C++如果两个模板函数都与参数列表匹配,将调用哪个模板
- 如果结构中的字符串比使用的 p/调用签名长或短,会发生什么情况?
- Qt信号和插槽如果从QRunnable或其他线程调用,则不起作用
- 如果 C函数确实存在,则 C++ 调用它
- 如果我从不调用这个方法,我可以把static_assert放在类方法中吗
- 我打算调用initializer_list构造函数,如果存在,则事先调用复制构造函数:为什么?
- 如果语句表达式调用函数,则需要测试是否为 true
- 如果我提前将参数声明为变量而不是将它们内联写入函数调用,那有什么区别(在内存方面)?
- 如果调用 RtlSetProcessIsCritical,将使用 lstrcmpW 将命令行与值进行比较将使程序崩溃
- C++如果调用 vector,矢量分割错误会导致崩溃
- 如何超载操作员 如果调用对象不是类对象
- 事件上的waitforsingleobject如果调用rssetscissercrect,会导致访问违规
- 如果调用某些函数,我可以强制编译器错误吗?
- 如何调用运算符内部的方法>如果调用的 methord 需要更改数据成员?
- 如果调用未覆盖的虚方法,如何强制生成编译器错误?
- 如果C++调用堆栈的顶部"???"所有零作为地址,这意味着什么?
- 如果调用 fclose(0),则关闭标准