我需要一些糟糕的C++代码示例来说明违反良好做法的行为.我想提出我自己的例子,但是我很难想出一些没有做作的例子,而且陷阱不是很明显(它比看起来更难).
例子如下:
std::auto_ptr成员的类定义复制构造函数,并使用std::auto_ptr具有前向声明的类的成员.boost::shared_ptr.size_t和的不匹配int).......或者你能想到的任何其他邪恶的东西.
我很欣赏对现有资源或一两个样本的一些指示.
In *_*ico 35
最令人烦恼的解析是C++解析这样的事情的一种令人惊讶的违反直觉的结果:
// Declares a function called "myVector" that returns a std::vector<float>.
std::vector<float> myVector();
// Does NOT declare an instance of std::vector<float> called "myVector"
// Declares a function called "foo" that returns a Foo and accepts an unnamed
// parameter of type Bar.
Foo foo(Bar());
// Does NOT create an instance of Foo called "foo" nor creates a Bar temporary
// Declares a function called "myVector" that takes two parameters, the first named
// "str" and the second unnamed, both of type std::istream_iterator<int>.
std::vector<float> myVector(
std::istream_iterator<int>(str),
std::istream_iterator<int>()
);
// Does NOT create an instance of `std::vector<float>` named "myVector" while copying
// in elements from a range of iterators
Run Code Online (Sandbox Code Playgroud)
这对任何不熟悉这种特殊语言的人(我自己开始学习C++时都包含在内)都会感到惊讶.
Pal*_*mik 16
#include <iostream>
class Base
{
public:
virtual void foo() const { std::cout << "A's foo!" << std::endl; }
};
class Derived : public Base
{
public:
void foo() { std::cout << "B's foo!" << std::endl; }
};
int main()
{
Base* o1 = new Base();
Base* o2 = new Derived();
Derived* o3 = new Derived();
o1->foo();
o2->foo();
o3->foo();
}
Run Code Online (Sandbox Code Playgroud)
输出是:
A's foo!
A's foo!
B's foo!
Run Code Online (Sandbox Code Playgroud)
不确定它是否有名字,但肯定是邪恶的!:P
In *_*ico 13
非异常安全的代码可能以对代码读者不明显的方式失败:
// Order of invocation is undefined in this context according to the C++ standard.
// It's possible to leak a Foo or a Bar depending on the order of evaluation if one
// of the new statements throws an exception before their auto_ptrs can "own" it
accept_two_ptrs(std::auto_ptr<Foo>(new Foo), std::auto_ptr<Bar>(new Bar));
void MyClass::InvokeCallback(CallbackType cb)
{
Foo* resource = new Foo;
cb(resource); // If cb throws an exception, resource leaks
delete resource;
}
Run Code Online (Sandbox Code Playgroud)
这一个今晚早些时候出现了.正如@ Billy ONeal在该帖子上指出的那样,eof()如果在流上发生错误,循环输入流(仅检查)会导致无限循环. good()应该用来代替.
坏:
while( !cin.eof() ) {
getline(cin, input);
}
Run Code Online (Sandbox Code Playgroud)
好:
while( cin.good() ) {
getline(cin, input);
}
Run Code Online (Sandbox Code Playgroud)
[来源:@James McNellis]
优秀:
while (std::getline(std::cin, input)) {
}
Run Code Online (Sandbox Code Playgroud)
您认为该计划将如何打印?
#include <iostream>
using namespace std;
struct A {
void f(int) { cout << "a" << endl; }
};
struct B: public A {
void f(bool) { cout << "b" << endl; }
};
int main() {
B b;
b.f(true);
b.f(1);
A* a = &b;
a->f(true);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
答:b,b,a!第一次打印输出很明显.第二个是b因为定义B::f(bool)隐藏了定义A::f(int).第三个是a因为重载解析发生在静态类型上.
(来源:本周大师,但我找不到文章.)
大多数C++程序员都不太了解Argument-Dependent Lookup(ADL,也称为Koenig查找),并且可能会导致一些非常不寻常的结果,尤其是与模板结合使用时.
重载决策涉及很多复杂性.在命名空间范围内使用指令时经常会出现问题,特别是using namespace std因为该命名空间有大量具有通用名称的实体.
以下是两个最近using namespace std导致问题的例子: