请考虑以下代码:
class Foo {
public:
explicit Foo(double) {}
};
Foo * test();
Foo * test() {
return new Foo(Foo(1.0)); // (1)
}
Run Code Online (Sandbox Code Playgroud)
我的问题涉及第(1)行.这非常类似于我花了一些时间来追踪的错误.由于复制/粘贴错误,我没有注意到该类型已被指定两次.显然,正确的路线是:
return new Foo(1.0);
Run Code Online (Sandbox Code Playgroud)
有趣的是,这种变化似乎也可以免费编译:
return new Foo(Foo(Foo(Foo(1.0))));
Run Code Online (Sandbox Code Playgroud)
为什么这些例子在没有警告的情况下编译,即使有-Wall -Weverything标志?为什么Foo::Foo(double)接受Foo的实例作为有效double参数?这是运营商新的一些特殊行为吗?
我的原始代码是在更大的上下文中,并使用两个基于LLVM-3的编译器进行测试.编译时都没有警告或错误.有一个,代码实际上按照我的预期运行,实际上我没有意识到有一段时间有一个bug.另一方面,Foo的实例表现得非常奇怪 - 我无法正确描述它 - 就好像后来的返回指针的副本"神奇地"变成了与原始值不同的值,导致两个合作之间的状态不匹配应该保存与共享Foo等效指针的对象,但由于某种原因在赋值后保存了不同的值.在我了解这里发生了什么之前,它似乎真的很奇怪!
有趣的是,以下两个编译器编译:
class Foo { public: explicit Foo(double) {} };
class Bar { public: explicit Bar(double) {} };
Foo * testFoo() { return new Foo(Foo(1.0)); }
Bar * testBar() { return new Bar(Bar(1.0)); }
Run Code Online (Sandbox Code Playgroud)
但是以下版本没有:
Foo * testFooBar() …Run Code Online (Sandbox Code Playgroud) 使用强制转换构造函数不好吗?否则为什么代码质量检查器(在我的例子中是 cppcheck)会不断建议在单参数构造函数之前添加显式?
如果我想做怎么办
class MyClass {
A(int) {}
};
A a = 1;
Run Code Online (Sandbox Code Playgroud)
如果我按照“建议”写
class MyClass {
explicit A(int) {}
};
A a = 1;
Run Code Online (Sandbox Code Playgroud)
会抛出一个错误,但如果我使用第一个,我会收到一个警告,我必须记录以通过代码审查。
这段代码有什么问题,如何解决?
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <vector>
struct CTest
{
CTest()
{ std::cout << "ctor CTest" <<std::endl; }
~CTest()
{ std::cout << "dtor CTest" <<std::endl; }
};
struct CSlot
{
CSlot() : m_test(new CTest()), m_num(123)
{ }
~CSlot()
{
// m_test.reset(); // this line fixed the code but I don't know why
m_num = -1;
}
boost::shared_ptr<CTest> m_test;
int m_num;
};
int main()
{
std::vector<CSlot> testVector(1);
std::cout << "1" << std::endl;
new (&testVector[0]) CSlot();
// clear slot
testVector[0].~CSlot();
std::cout << …Run Code Online (Sandbox Code Playgroud) 我想创建一个类MPSList,其中构造函数具有与之关联的显式关键字.
以下是最小的代码:
class MPSList {
public:
explicit MPSList(int n) : n_(n) {
mpsL.resize(n_, std::vector<MPSNode>{});
std::cout << mpsL.size() << std::endl;
}
private:
struct MPSNode {
double s_;
};
std::vector<std::vector<MPSNode>> mpsL;
int n_ = -1;
};
Run Code Online (Sandbox Code Playgroud)
创建MPSList类对象的CPP文件.
#include <iostream>
#include "MPSList.hpp"
int main() {
double n = 10.9;
MPSList mps(n);
}
Run Code Online (Sandbox Code Playgroud)
在编译上面的CPP文件时,我原本期望在初始化对象时看到错误.当我传递一个double时,构造函数显然期望一个int.
编译命令:
g++ -std=c++14 -I../include test.cpp
./a.out
Run Code Online (Sandbox Code Playgroud) 在下面的示例中,由于抽象方法,我的类是抽象的run。我还有一个来自另一种类型的构造函数。我总是将只有 1 个参数的构造函数标记为explicit,除非我希望隐式强制转换可用。但是,在抽象类的特殊情况下,有什么理由证明它是合理的吗?
class Foo
{
public:
virtual void run() = 0; // Then the class is abstract
explicit Foo(Bar const& bar);
};
Run Code Online (Sandbox Code Playgroud)
注意:我的问题纯粹是技术性的:有没有办法在抽象类的构造函数上使用或不使用显式关键字来实现不同的行为?
我对此有疑问:
class A
{
int a;
int* pa;
public:
A(int i):a(i) , pa(new int(a))
{
cout<<"A ctor"<<a<<endl;
}
~A()
{
delete pa;
cout<<"dtor\n";
}
int * &get()
{
return pa;
}
};
class B : public A
{
int b;
public:
B (A obj): A(obj) , b(0)
{
cout<<"B ctor\n";
}
~B()
{
cout<<"B dtor\n";
}
};
int main()
{
int i = 23 ;
A* p = new B(i);
}
Run Code Online (Sandbox Code Playgroud)
可以告诉我为什么最后一行main编译?我传递一个int进入B的构造,其预期的A目的,而不是.我相信它 …
我正在编写一个类,该类具有带const char*参数的显式构造函数。为了这个问题的目的和目的,它看起来像这样:
struct Symbol
{
Symbol()=default;
explicit Symbol(const char*);
};
Run Code Online (Sandbox Code Playgroud)
现在,出于文档目的,我想编写一个示例来初始化一个数组(array / vector / list-我不在乎确切的类型),并且我需要该示例尽可能简洁明了。理想的情况是这样的:
Symbol symbols[] = { "a", "b", "c"};
Run Code Online (Sandbox Code Playgroud)
由于explicit关键字,因此无法编译,因此我不准备将构造函数设为隐式。
我如何使这项工作有效,重点在于使示例代码尽可能具有表现力?
编辑:在Caleth的一点帮助下,我寻求Bolov的解决方案:
struct Symbol
{
Symbol();
explicit Symbol(const char*);
template <class... Args>
static std::array<Symbol, sizeof...(Args)> Array(Args... args)
{
return {Symbol{args}...};
}
};
int main()
{
auto symbols = Symbol::Array("a", "b", "c");
}
Run Code Online (Sandbox Code Playgroud) c++ ×7
explicit ×2
c++11 ×1
constructor ×1
cppcheck ×1
destructor ×1
inheritance ×1
new-operator ×1
shared-ptr ×1
valgrind ×1