我已经用C++编程了几年,我已经使用了很多STL并且已经创建了我自己的模板类几次以了解它是如何完成的.
现在我正在尝试将模板更深入地集成到我的OO设计中,一个唠叨的想法不断回到我身边:它们只是一个宏,真的......你可以使用#defines实现(而不是UGLY)auto_ptrs,如果你真的想要.
这种思考模板的方式有助于我理解我的代码将如何实际工作,但我觉得我必须以某种方式忽略这一点.宏是邪恶的化身,但"模板元编程"风靡一时.
那么,真正的区别是什么?模板如何避免#define引导你进入的危险,比如
我已经习惯了Delphi VCL框架,其中TStreams会在错误上抛出异常(例如找不到文件,磁盘已满).我正在移植一些代码来代替使用C++ STL,并且已被iostream捕获而不是默认情况下抛出异常,而是设置badbit/failbit标志.
两个问题......
a:为什么这样 - 对于从第一天开始就使用异常构建的语言,这似乎是一个奇怪的设计决策?
b:如何最好地避免这种情况?我可以按照我的预期生产可以抛出的垫片类,但这就像重新发明轮子一样.也许有一个BOOST库以更加理智的方式做到这一点?
我试图让我的头围绕元组(感谢@litb),他们使用的常见建议是返回> 1值的函数.
这是我通常使用结构的东西,在这种情况下我无法理解元组的优点 - 对于最终的懒惰来说,这似乎是一种容易出错的方法.
借用一个例子,我会用它
struct divide_result {
int quotient;
int remainder;
};
Run Code Online (Sandbox Code Playgroud)
使用元组,你会有
typedef boost::tuple<int, int> divide_result;
Run Code Online (Sandbox Code Playgroud)
但是如果你没有阅读你正在调用的函数的代码(或者评论,如果你足够愚蠢地信任它们),你就不知道哪个int是商,反之亦然.看起来很像......
struct divide_result {
int results[2]; // 0 is quotient, 1 is remainder, I think
};
Run Code Online (Sandbox Code Playgroud)
......这不会让我满怀信心.
那么,什么是元组在该补偿的模糊性结构的优势是什么?
我看到它使用了很多,但没有看到完全有意义的定义.
维基词典说 "具有足够或优秀的性能或效率水平",这没有多大帮助.
最初,虽然高性能只是意味着"快速",但其他人似乎认为它也与稳定性,代码质量,内存使用/占用空间或所有这些的某种组合有关.
我认为这是一个"真实"的问题 - 但如果有足够的人认为这是一个主观问题,那本身就是一个答案.
偶尔,尽管进行了所有的测试工作,我仍然会遇到一个客户的错误报告,我无法在办公室重现.

(向杰夫申请"借用"徽章)
我有一些"工具",我可以尝试找到并修复它们,但它总是让我觉得有点像刀和它一样: -
是否有设置程序或其他技术比任何人用来解决这样的问题?
我熟悉RAII的优点,但我最近在这样的代码中遇到了问题:
class Foo
{
public:
Foo()
{
DoSomething();
...
}
~Foo()
{
UndoSomething();
}
}
Run Code Online (Sandbox Code Playgroud)
一切都很好,除了构造函数...部分中的代码抛出异常,结果UndoSomething()从未被调用.
有明显的方法来解决这个特定的问题,比如...在一个try/catch块然后调用UndoSomething(),但是a:那是重复的代码,而b:try/catch块是一种代码气味,我试图通过使用RAII技术来避免.而且,如果涉及多个Do/Undo对,代码可能会变得更糟,更容易出错,而且我们必须在中途进行清理.
我想知道有一个更好的方法来做到这一点 - 也许一个单独的对象需要一个函数指针,并在它反过来被破坏时调用该函数?
class Bar
{
FuncPtr f;
Bar() : f(NULL)
{
}
~Bar()
{
if (f != NULL)
f();
}
}
Run Code Online (Sandbox Code Playgroud)
我知道不会编译,但它应该显示原则.Foo然后变成......
class Foo
{
Bar b;
Foo()
{
DoSomething();
b.f = UndoSomething;
...
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,foo现在不需要析构函数.这听起来比它的价值更麻烦吗,或者这已经是一个常见的模式,有助于我处理繁重的事情吗?
我刚刚用bitfields做了一个测试,结果令我感到惊讶.
class test1 {
public:
bool test_a:1;
bool test_b:1;
bool test_c:1;
bool test_d:1;
bool test_e:1;
bool test_f:1;
bool test_g:1;
bool test_h:1;
};
class test2 {
public:
int test_a:1;
int test_b:1;
int test_c:1;
int test_d:1;
int test_e:1;
int test_f:1;
int test_g:1;
int test_h:1;
};
class test3 {
public:
int test_a:1;
bool test_b:1;
int test_c:1;
bool test_d:1;
int test_e:1;
bool test_f:1;
int test_g:1;
bool test_h:1;
};
Run Code Online (Sandbox Code Playgroud)
结果如下: -
sizeof(test1) = 1 // This is what I'd expect. 8 bits in a byte …Run Code Online (Sandbox Code Playgroud) 我有这段代码(总结)......
AnsiString working(AnsiString format,...)
{
va_list argptr;
AnsiString buff;
va_start(argptr, format);
buff.vprintf(format.c_str(), argptr);
va_end(argptr);
return buff;
}
Run Code Online (Sandbox Code Playgroud)
并且,在可能的情况下优先考虑通过参考,我因此改变了它.
AnsiString broken(const AnsiString &format,...)
{
... the rest, totally identical ...
}
Run Code Online (Sandbox Code Playgroud)
我的主叫代码是这样的: -
AnsiString s1, s2;
s1 = working("Hello %s", "World");
s2 = broken("Hello %s", "World");
Run Code Online (Sandbox Code Playgroud)
但是,s1包含"Hello World",而s2包含"Hello(null)".我认为这是由于va_start的工作方式,但我不确定是怎么回事.
不使用实例/引用计数器的Singleton对象是否应被视为C++中的内存泄漏?
如果没有计数器在计数为零时要求显式删除单例实例,该对象如何被删除?当应用程序终止时,操作系统是否清理它?如果那个Singleton在堆上分配了内存怎么办?
简而言之,我是否必须调用Singelton的析构函数,还是可以依赖它在应用程序终止时进行清理?
c++ ×7
exception ×2
bit-fields ×1
boost-tuples ×1
c ×1
debugging ×1
history ×1
iostream ×1
macros ×1
numerical ×1
performance ×1
raii ×1
reference ×1
singleton ×1
stl ×1
templates ×1
terminology ×1
testing ×1
tuples ×1