实施C++;C#using语句的等价形式 我正在寻找一个优雅的解决方案,用于实现C++中使用C语句的等价性。理想情况下,生成的语法应该易于使用和阅读
C#使用报表的详细信息如下-实施C++;C#using语句的等价形式 我正在寻找一个优雅的解决方案,用于实现C++中使用C语句的等价性。理想情况下,生成的语法应该易于使用和阅读,c#,c++,templates,using-statement,C#,C++,Templates,Using Statement,C#使用报表的详细信息如下- 我不确定解决方案是否是在类上使用带析构函数的函数指针,某种形式的智能模板编程,甚至元模板编程。基本上我不知道从哪里开始 > P>不需要在C++中实现这一点,因为RAIII的标准模式已经完成了您需要的。 { ofstream myfile; myfile.open("hello.txt"); myfile << "Hello\n"; } { 流文件; myfile.open(“hello.txt”); myfile我想看看如何使
我不确定解决方案是否是在类上使用带析构函数的函数指针,某种形式的智能模板编程,甚至元模板编程。基本上我不知道从哪里开始 > P>不需要在C++中实现这一点,因为RAIII的标准模式已经完成了您需要的。
{
ofstream myfile;
myfile.open("hello.txt");
myfile << "Hello\n";
}
{
流文件;
myfile.open(“hello.txt”);
myfile我想看看如何使用std::auto_ptr处理分配给特定范围内指针的任何实例的清理——否则,在特定范围内声明的任何变量在退出所述范围时都将被销毁
{
SomeClass A;
A.doSomething();
} // The destructor for A gets called after exiting this scope here
{
SomeClass* pA = new SomeClass();
std::auto_ptr<SomeClass> pAutoA(pA);
pAutoA->doSomething();
} // The destructor for A also gets called here, but only because we
// declared a std::auto_ptr<> and assigned A to it within the scope.
{
甲级;
A.doSomething();
}//在此处退出此作用域后,将调用的析构函数
{
SomeClass*pA=新的SomeClass();
std::自动ptr pAutoA(pA);
pAutoA->doSomething();
}//此处也会调用A的析构函数,但这只是因为
//声明了一个std::auto_ptr,并在范围内为其分配了一个。
有关std::auto_ptr的更多信息,请参阅。我建议您阅读以下链接:
类似于C#的using语句的更详细的RAII模式可以通过一个简单的宏来实现
#define Using(what, body) { what; body; }
Using(int a=9,
{
a++;
})
a++; // compile error, a has gone out of scope here
注意,我们必须使用大写的“Using”来避免与C++内置的“Using”语句发生冲突,这显然具有不同的含义。首先,我们必须定义一个可关闭/一次性的公共接口:
#include <iostream>
using namespace std;
class Disposable{
private:
int disposed=0;
public:
int notDisposed(){
return !disposed;
}
void doDispose(){
disposed = true;
dispose();
}
virtual void dispose(){}
};
以下是一个示例应用程序:
class Connection : public Disposable {
private:
Connection *previous=nullptr;
public:
static Connection *instance;
Connection(){
previous=instance;
instance=this;
}
void dispose(){
delete instance;
instance = previous;
}
};
Connection *Connection::instance = nullptr;
int Execute(const char* query){
if(Connection::instance == nullptr){
cout << "------- No Connection -------" << endl;
cout << query << endl;
cout << "------------------------------" << endl;
cout << endl;
return -1;//throw some Exception
}
cout << "------ Execution Result ------" << endl;
cout << query << endl;
cout << "------------------------------" << endl;
cout << endl;
return 0;
}
int main(int argc, const char * argv[]) {
using(new Connection())
{
Execute("SELECT King FROM goats");//in the scope
}
Execute("SELECT * FROM goats");//out of the scope
}
我被告知RAII涵盖了这一点。正如Anthony所说,使用RAII将自动为您做到这一点,而且imho,它使代码比使用模式更干净。从我的观点来看,使用
关键字只是一种平庸的补救方法,因为一开始就没有RAII。因此,您不应该试图模仿它。@Andre它有点难.我想C#编译器可以将作用域IDisposable处理为类似于RAII的,但我不确定它如何知道处理对象是否安全。当对象离开作用域时,可能会检查ref计数,如果0,则立即调用dispose?@DavidHeffernan我说的是不必使用使用作用域。很高兴知道,谢谢。大多数时候,我通常坚持Boost库……除了AutoTypTR和UnjyQu.Pt.Objor之外还有其他的,这比使用< /C> >的C>代码>要优越,而且它也与C++中的.NET对象一起工作。C++语法要好得多,因为尽管你仍然需要记住使用值语义语法:(1)您可以对每种类型使用它,无论它是否实现了IDisposable
,或者对于接口,不同的对象可以使用,也可以不使用,以及(2)它对类成员有效。我认为这不是一件更好或更坏的事情,而是你在环境中处理问题的工具。C++使用堆作为内存管理,也可以堆栈,但是它没有垃圾收集,所以这就是GGC延迟内存管理的区别,它有它自己的优势,所以应该怎么做?在这种情况下,我做什么工作?我们不是不同的运动团队,我们是处理不同技术的开发人员……我不明白这是一个公认的答案,而且通过这么多的投票,因为RAII只是一个设计负责人。如果说RAII一直负责所有事情,这不是让你自己陷于失败吗?更好的答案更类似于C#的using
语句的是用法,更具体地说,正如这里的另一个答案所提到的。智能指针在分配的调用端为您实现了一个RAII包装器,与using
非常类似。我喜欢这一点,因为我喜欢“using”的显式本质。至于宏本身,我喜欢它还有一个更好。
class Connection : public Disposable {
private:
Connection *previous=nullptr;
public:
static Connection *instance;
Connection(){
previous=instance;
instance=this;
}
void dispose(){
delete instance;
instance = previous;
}
};
Connection *Connection::instance = nullptr;
int Execute(const char* query){
if(Connection::instance == nullptr){
cout << "------- No Connection -------" << endl;
cout << query << endl;
cout << "------------------------------" << endl;
cout << endl;
return -1;//throw some Exception
}
cout << "------ Execution Result ------" << endl;
cout << query << endl;
cout << "------------------------------" << endl;
cout << endl;
return 0;
}
int main(int argc, const char * argv[]) {
using(new Connection())
{
Execute("SELECT King FROM goats");//in the scope
}
Execute("SELECT * FROM goats");//out of the scope
}
int main(int argc, const char * argv[]) {
{
int i=23;
}
// the variable i has been deleted from the momery at here.
}
#define USING(...) if(__VA_ARGS__; true)
USING(int i = 0)
USING(std::string s = "0")
{
Assert::IsTrue(i == 0, L"Invalid result", LINE_INFO());
Assert::IsTrue(s == "0", L"Invalid result", LINE_INFO());
}
//i = 1; // error C2065: 'i': undeclared identifier
//s = "1"; //error C2065: 's': undeclared identifier