假设我有一个名为caller的函数,它将调用一个名为callee的函数:
void caller()
{
callee();
}
Run Code Online (Sandbox Code Playgroud)
现在可以在应用程序中多次调用调用者,并且您希望确保只调用一次调用者.(一种懒惰的初始化),你可以使用一个标志来实现它:
void caller()
{
static bool bFirst = true;
if(bFirst)
{
callee();
bFirst = false;
}
}
Run Code Online (Sandbox Code Playgroud)
我的意见是它需要更多的代码,并且每次调用函数调用者都需要再检查一次.
对我来说更好的解决方案如下:(假设被调用者返回int)
void caller()
{
static int ret = callee();
}
Run Code Online (Sandbox Code Playgroud)
但如果callee返回void,则无法处理此情况,我的解决方案是使用逗号表达式:
void caller()
{
static int ret = (callee(), 1);
}
Run Code Online (Sandbox Code Playgroud)
但问题在于,逗号表达式并不常用,人们在看到这行代码时可能会感到困惑,从而导致维护问题.
你有什么好主意确保只调用一次函数吗?
我要求在Windows中的32位WOW进程中检索64位进程的所有模块,EnumProcessModules将失败,如下所述:
如果从WOW64上运行的32位应用程序调用此函数,则它只能枚举32位进程的模块.如果进程是64位进程,则此函数失败,最后一个错误代码为ERROR_PARTIAL_COPY(299).
以便EnumProcessModulesEx和CreateToolhelp32Snapshot.
你对如何实现它有任何想法吗?
谢谢.
我想知道是否可以让编译器为代码发出警告/错误,如下所示:
注意:
1.是的,这是糟糕的编程风格,我们应该避免这种情况 - 但我们正在处理遗留代码,并希望编译器可以帮助我们识别这些情况.)
2.我更喜欢编译器选项(VC++)来禁用或启用对象切片(如果有的话).
class Base{};
class Derived: public Base{};
void Func(Base)
{
}
//void Func(Derived)
//{
//
//}
//main
Func(Derived());
Run Code Online (Sandbox Code Playgroud)
在这里,如果我注释掉第二个函数,第一个函数将被调用 - 而编译器(VC++和Gcc)对此感觉很舒服.
它是C++标准吗?并且我可以问编译器(VC++)在遇到这样的代码时给我一个警告吗?
非常感谢!!!
编辑:
非常感谢你的帮助!
我找不到一个编译器选项来给出错误/警告 - 我甚至在MSDN论坛上发布了这个VC++编译器顾问没有回答.所以我担心gcc和vc ++都没有实现这个功能.
因此,添加构造函数将派生类作为参数将是目前最好的解决方案.
编辑
我已经向MS提交了一个feedbak,希望他们能尽快修复它:
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=421579
-Baiyan
有许多免费的在线服务,为您提供了大量的空间来存储您的个人材料,邮件等.但是有没有地方可以让我们托管我们的代码 - 这保持了变化的历史?
谷歌代码或SourceForge可能不是一个理想的地方,因为它需要创建一个对他人特定和有用的项目,而我想要的是一个存放任何类型的代码的地方,我认为这些代码很有用但可能不适合其他任何人.
我有以下代码:
#include <functional> // std::less
#include <map>
#include <iostream>
using namespace std;
class Key
{
public:
Key() {cout << "Key Constructor" << endl;}
~Key() {cout << "Key Destructor" << endl;}
Key(const Key& key) {cout << "Key Copy Constructor" << endl;}
bool operator < (const Key& k1) {return true;}
};
int main()
{
map<Key, int> mymap;
Key k;
cout << "operator[]"<<endl;
mymap[k] = 1;
map<Key, int> mymap2;
cout << "insert"<<endl;
mymap2.insert(std::make_pair(k, 1));
cout << "=========" << endl;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
$ g++ …
Run Code Online (Sandbox Code Playgroud) 我正在编写一个非常简单的模板类,使用元编程在编译时计算总和,如下所示:
#include <iostream>
using namespace std;
template<int N>
class Sum
{
public:
enum {value = N + Sum<N-1>::value };
};
template<>
class Sum<0>
{
public:
enum {value = 0};
};
int main()
{
cout << Sum<501>::value << endl;
}
Run Code Online (Sandbox Code Playgroud)
有趣的是:
当谈到Sum <501>时,编译失败了:
sum.cpp:9:从
Sum<500>' sum.cpp:9: instantiated from
Sum <501>'sum.cpp:22实例化:从这里实例化sum.cpp:9:错误:不完整的类型
Sum<1>' used in nested name specifier sum.cpp:9: error: enumerator value for
值'不是整数常量
Sum <501>将报告Sum <1>的错误,Sum <502>将报告Sum <2>的错误,差值始终为2,在我看来编译器的限制资源为500.
对此有何想法?他们是打破这种限制的一种方式吗?
谢谢.
编辑:
谢谢大家,重点不是关于算法,而是编译器的限制 - 我知道有一个简单的方法来获得总和:)
EDIT2:
sum.cpp:9:14:错误:模板实例化深度超过1024的最大值(使用-ftemplate-depth …
Lua声称它正确实现尾调用,因此不需要为每个调用维护堆栈,因此允许无限递归,我试图写一个求和函数,一个不是尾调用,一个是尾调用:
非tailcall版本
function sum(n)
if n > 0 then
return n + sum(n-1)
end
end
print(sum(1000000))
Run Code Online (Sandbox Code Playgroud)
stackoverflow正如预期的那样.
tailcall版本
function sum2(accu, n)
if n > 0 then
accu.value = accu.value + n
sum2(accu, n-1)
end
end
local accu = {value = 0}
sum2(accu, 1000000)
print(accu.value)
Run Code Online (Sandbox Code Playgroud)
我想在这种情况下不存在stackoverflow,因为它是一个tailcall,但由于stackoverflow它仍然失败:
/bin/lua/5.1.4/bin/lua: tailcall.lua:13: stack overflow
stack traceback:
tailcall.lua:13: in function 'sum2'
tailcall.lua:13: in function 'sum2'
tailcall.lua:13: in function 'sum2'
tailcall.lua:13: in function 'sum2'
tailcall.lua:13: in function 'sum2'
tailcall.lua:13: in function 'sum2'
tailcall.lua:13: in function …
Run Code Online (Sandbox Code Playgroud) 假设我有这样的要求:
系统中的对象都派生自一个名为IObject的基类,它可能包含带颜色的对象,带有转换的对象,以及两者.
现在有两种方法来设计类层次结构.
第一个是:
只是让具体类派生自IObject,并选择"capability"接口作为其基类来表示它支持这样的行为,如interface:IHasColor,
IHasTransformation
第二个是:
组织基类,并从其中一个派生出具体类:IObject,IColorObject,ITransfromationObject,IColorAndTransformationObject
我更喜欢第一个(它有一个正式的名字?)因为它更灵活,你可以看到第二个可能有类组合爆炸问题,当有许多属性,如颜色,转换...
我想知道你的想法和建议.
谢谢.
要将许多数据写入文件,我有两种方法:
直接写入ofstream流
ofstream file("c:\\test.txt");
for (int i = 0; i < 10000; ++i)
{
file << data[i];
}
Run Code Online (Sandbox Code Playgroud)首先写入istringstream,然后立即写入ofstream
ostringstream strstream;
for (int i = 0; i < 10000; ++i)
{
strstream << data[i];
}
ofstream file("c:\\test.txt");
file << strstream.str();
Run Code Online (Sandbox Code Playgroud)毫不奇怪,第二种方法更快,事实上,它比我的HP7800机器上的第一种方法快4倍.
但为什么?我知道ofstream正在使用filebuf,而ostringstream正在使用stringbuf - 作为缓冲区,它们都应该驻留在内存中,因此应该没有区别.
引擎盖下有什么区别?
c++ ×5
windows ×2
32bit-64bit ×1
batch-file ×1
constructor ×1
filestream ×1
hosting ×1
interface ×1
iostream ×1
lua ×1
map ×1
oop ×1
process ×1
repository ×1
slice ×1
stl ×1
templates ×1
truncate ×1
wow64 ×1