使用语句实现C#的C++等价物
Implementing C++ equivalent of C# using statement
我正在寻找一个优雅的解决方案,用于在C++中实现等价的C#using语句。理想情况下,生成的语法应该易于使用和阅读。
C#使用语句的详细信息如下-http://msdn.microsoft.com/en-us/library/yh598w02(v=vs.80).aspx
我不确定解决方案是在类上使用带析构函数的函数指针,还是某种形式的巧妙模板编程,甚至是元模板编程。基本上我不知道从哪里开始。。。
您不需要在C++中实现这一点,因为RAII的标准模式已经满足了您的需求。
{
ofstream myfile;
myfile.open("hello.txt");
myfile << "Hellon";
}
当块作用域结束时,myfile
将被销毁,从而关闭文件并释放与对象相关联的任何资源。
using
语句存在于C#中的原因是为了围绕try/finaly和IDisposable
提供一些语法糖。C++中根本不需要它,因为这两种语言不同,而且每种语言解决问题的方式也不同。
我来看看如何使用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.
请参阅http://en.wikipedia.org/wiki/Auto_ptr有关std::auto_ptr<>的更多信息
一个更详细的RAII模式,类似于C#的using语句,可以用一个简单的宏来实现。
#define Using(what, body) { what; body; }
Using(int a=9,
{
a++;
})
a++; // compile error, a has gone out of scope here
注意,我们必须使用大写的"Using"来避免与C++内置的"Using"语句发生冲突,后者显然有不同的含义。
#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
首先,我们必须定义一个可关闭/可丢弃的公共接口:
#include <iostream>
using namespace std;
class Disposable{
private:
int disposed=0;
public:
int notDisposed(){
return !disposed;
}
void doDispose(){
disposed = true;
dispose();
}
virtual void dispose(){}
};
然后我们应该为using关键字定义一个宏:
#define using(obj) for(Disposable *__tmpPtr=obj;__tmpPtr->notDisposed();__tmpPtr->doDispose())
以及;下面是一个应用程序示例:
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.
}
我建议阅读以下链接:
- C++RAII与Java Dispose模式的比较
- C++、C#和Java中的构造函数异常
- 更多C++习语/资源获取是初始化
- 资源获取是初始化(RAII)
作为其他答案的替代方案,它强调RAII对象,不需要宏,语法与C#非常相似:
if(std::ofstream myfile("hello.txt"); true) {
// code
};
该对象与大括号内的代码分开,与C#中的相同
using (StreamReader reader = File.OpenText("hello.txt")) {
// code
}
当然,像C#中那样单独使用关键字,而不是if
会更好。
使用宏,类似于C#语法:
#define Using(what) if(what; true)
Using(std::ofstream myfile("hello.txt")) {
// code
};
需要C++17。
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- python集合的C++等价物是什么.计数器
- C++中是否存在 std::conditional 的懒惰等价物?
- std::endl,在 Python 中是否有等价物?(返回 + 刷新)
- 在本征C++中 MKL 的函数"zgges"等价物是多少?
- 在C++中使用std或boost库的Qtimer等价物是什么
- GLM中的Java Matrix4.transform等价物
- 对于std::bitset,是否有一个ffs()等价物
- std::move() 或其在局部变量上的显式等价物可以允许 elision 吗?
- 这个 matlab 代码的C++等价物是什么(fread matlab vs fread C/C++)?
- 对于wchar_t,字符(0)或'