在阅读 Bjarne Stroustrup 的 CoreCppGuidelines 时,我发现了一个与我的经验相矛盾的指南。
C.21需要以下内容:
If you define or
=deleteany default operation, define or=deletethem all
原因如下:
The semantics of the special functions are closely related, so if one needs to be non-default, the odds are that others need modification too.
根据我的经验,重定义默认操作最常见的两种情况如下:
#1:使用默认主体定义虚拟析构函数以允许继承:
class C1
{
...
virtual ~C1() = default;
}
#2:定义默认构造函数,对 RAII 类型的成员进行一些初始化:
class C2
{
public:
int a; float b; std::string c; std::unique_ptr<int> x;
C2() : a(0), b(1), c("2"), x(std::make_unique<int>(5))
{}
}
根据我的经验,所有其他情况都很少见。
您如何看待这些例子?它们是 C.21 规则的异常(exception),还是最好在此处定义所有默认操作?还有其他常见的异常(exception)吗?
最佳答案
我对这个指南有很大的保留意见。即使知道这是指南,而不是规则,我仍然有所保留。
假设您有一个类似于 std::complex<double> 的用户编写的类, 或 std::chrono::seconds .它只是一个值类型。它不拥有任何资源,它很简单。假设它有一个非特殊成员的构造函数。
class SimpleValue
{
int value_;
public:
explicit SimpleValue(int value);
};
嗯,我也想要SimpleValue是默认可构造的,并且我通过提供另一个构造函数来禁止默认构造函数,所以我需要添加那个特殊成员:
class SimpleValue
{
int value_;
public:
SimpleValue();
explicit SimpleValue(int value);
};
我担心人们会记住这个准则和理由:好吧,既然我提供了一个特殊的成员,我应该定义或删除其余的,所以这里......
class SimpleValue
{
int value_;
public:
~SimpleValue() = default;
SimpleValue();
SimpleValue(const SimpleValue&) = default;
SimpleValue& operator=(const SimpleValue&) = default;
explicit SimpleValue(int value);
};
嗯...我不需要移动成员,但我需要盲目地遵循聪明人告诉我的内容,所以我将删除那些:
class SimpleValue
{
int value_;
public:
~SimpleValue() = default;
SimpleValue();
SimpleValue(const SimpleValue&) = default;
SimpleValue& operator=(const SimpleValue&) = default;
SimpleValue(SimpleValue&&) = delete;
SimpleValue& operator=(SimpleValue&&) = delete;
explicit SimpleValue(int value);
};
我担心 CoreCppGuidelines C.21 会导致大量看起来像这样的代码。为什么这么糟糕?几个原因:
1.这比这个正确的版本更难阅读:
class SimpleValue
{
int value_;
public:
SimpleValue();
explicit SimpleValue(int value);
};
2.它坏了。当您第一次尝试返回 SimpleValue 时,您会发现按值从函数中获取:
SimpleValue
make_SimpleValue(int i)
{
// do some computations with i
SimpleValue x{i};
// do some more computations
return x;
}
这不会编译。错误消息将说明有关访问 SimpleValue 的已删除成员的内容。 .
我有一些更好的指导方针:
1.了解编译器何时为您默认或删除特殊成员,以及默认成员将做什么。
此图表可以帮助您:
如果这张图表远过于复杂,我明白。它是复杂的。但是,当它一次向您解释一点时,处理起来会容易得多。 我希望在一周内更新此答案,并附上我解释此图表的视频链接。 这是解释的链接,延迟时间比我长会喜欢(我很抱歉):https://www.youtube.com/watch?v=vLinb2fgkHk
2.当编译器的隐式操作不正确时,总是定义或删除一个特殊的成员。
3.不要依赖已弃用的行为(上图中的红色框)。如果您声明了任何析构函数、复制构造函数或复制赋值运算符,则同时声明复制构造函数和复制赋值运算符。
4. 从不删除移动成员。如果这样做,充其量只是多余的。在最坏的情况下,它会破坏你的类(class)(如上面的 SimpleValue 示例)。如果您确实删除了 move 成员,并且这是多余的案例,那么您会迫使您的读者不断审查您的类(class),以确保它不是损坏的案例。
5.对这 6 个特殊成员中的每一个给予温柔的关怀,即使结果是让编译器为您处理它(可能通过隐式禁止或删除它们)。
6.将你的特殊成员以一致的顺序放在你的类的顶部(只有那些你想明确声明的),这样你的读者就不必去搜索它们了。我有我最喜欢的订单,如果您喜欢的订单不同,那很好。我的首选顺序是我在 SimpleValue 中使用的顺序。例子。
Here is a brief paper with more rationale for this style of class declaration.
关于c++ - CppCoreGuidelines C.21 是否正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38682675/
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife
我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案
我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查
我的日期格式如下:"%d-%m-%Y"(例如,今天的日期为07-09-2015),我想看看是不是在过去的七天内。谁能推荐一种方法? 最佳答案 你可以这样做:require"date"Date.today-7 关于ruby-检查日期是否在过去7天内,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/32438063/
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
question的一些答案关于redirect_to让我想到了其他一些问题。基本上,我正在使用Rails2.1编写博客应用程序。我一直在尝试自己完成大部分工作(因为我对Rails有所了解),但在需要时会引用Internet上的教程和引用资料。我设法让一个简单的博客正常运行,然后我尝试添加评论。靠我自己,我设法让它进入了可以从script/console添加评论的阶段,但我无法让表单正常工作。我遵循的其中一个教程建议在帖子Controller中创建一个“评论”操作,以添加评论。我的问题是:这是“标准”方式吗?我的另一个问题的答案之一似乎暗示应该有一个CommentsController参