实施 C++相当于 C# using 语句

发布于 2025-01-03 01:03:23 字数 333 浏览 1 评论 0原文

我正在寻找一种优雅的解决方案来实现 C++ 中 C# using 语句的等效项。理想情况下,生成的语法应该易于使用和阅读。

C# using 语句详细信息在这里 - http://msdn.microsoft.com/en- us/library/yh598w02(v=vs.80).aspx

我不确定解决方案是否是在类上使用带有析构函数的函数指针,这是某种形式的巧妙模板编程甚至元模板编程。基本上我不知道从哪里开始......

I am looking for an elegant solution for implementing the equivalent of the C# using statement in C++. Ideally the resultant syntax should be simple to use and read.

C# Using statement details are here -
http://msdn.microsoft.com/en-us/library/yh598w02(v=vs.80).aspx

I am not sure whether the solution would be to use function pointers with destructors on classes, some form of clever template programming or even meta template programming. Basically I do not know where to start with this...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

像极了他 2025-01-10 01:03:24

您不需要在 C++ 中实现它,因为 RAII 的标准模式已经满足您的需要。

{
    ofstream myfile;
    myfile.open("hello.txt");
    myfile << "Hello\n";
}

当块作用域结束时,myfile 将被销毁,从而关闭文件并释放与该对象关联的所有资源。

C# 中存在 using 语句的原因是为 try/finally 和 IDisposable 提供一些语法糖。在 C++ 中根本不需要它,因为两种语言不同,并且每种语言解决问题的方式也不同。

You don't need to implement this in C++ because the standard pattern of RAII already does what you need.

{
    ofstream myfile;
    myfile.open("hello.txt");
    myfile << "Hello\n";
}

When the block scope ends, myfile is destroyed which closes the file and frees any resources associated with the object.

The reason the using statement exists in C# is to provide some syntactic sugar around try/finally and IDisposable. It is simply not needed in C++ because the two languages differ and the problem is solved differently in each language.

ヤ经典坏疍 2025-01-10 01:03:24

我会看一下使用 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.

有关 std 的更多信息,请参阅 http://en.wikipedia.org/wiki/Auto_ptr ::auto_ptr<>;

I'd take a look at using std::auto_ptr<> to handle cleanup of any instances allocated and assigned to a pointer within a particular scope -- otherwise, any variables declared within a specific scope will simply be destructed when exiting said scope.

{
    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.

See http://en.wikipedia.org/wiki/Auto_ptr for a little more information on std::auto_ptr<>

爱给你人给你 2025-01-10 01:03:24

可以使用简单的宏来完成类似于 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”语句发生冲突,后者显然具有不同的含义。

A more verbose RAII pattern that resembles C#'s using statement can be accomplished with a simple macro.

#define Using(what, body) { what; body; }

Using(int a=9,
{
    a++;
})

a++; // compile error, a has gone out of scope here

Note we must use a capital "Using" to avoid a collision with C++'s built in "using" statement which obviously has a different meaning.

时光是把杀猪刀 2025-01-10 01:03:24
    #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
    #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
你列表最软的妹 2025-01-10 01:03:24

首先,我们必须定义一个 Closeable/Disposable 公共接口:

#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())

and;这是一个示例应用程序:

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.
} 

First, we have to define a Closeable/Disposable public interface:

#include <iostream>

using namespace std;


class Disposable{
private:
    int disposed=0;
public:
    int notDisposed(){
        return !disposed;
    }
    
    void doDispose(){
        disposed = true;
        dispose();
    }
    
    virtual void dispose(){}
    
};

Then we should define a macro for the using keyword:

#define using(obj) for(Disposable *__tmpPtr=obj;__tmpPtr->notDisposed();__tmpPtr->doDispose())

and; here is an example application:

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
    
}

But if you want to delete variables automatically from memory, you can simply use braces {}; therefore, every variable inside of the scope will be removed at the end of the scope.
here is an example:

int main(int argc, const char * argv[]) {
    {
        int i=23;
    } 
    
    // the variable i has been deleted from the momery at here.
} 
深海蓝天 2025-01-10 01:03:24

作为强调 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。

As an alternative to other answers that emphasizes your RAII object, doesn't require macros and has a very similar syntax to C#:

if(std::ofstream myfile("hello.txt"); true) {
    // code 
};

The object is put apart from the code inside the curly braces, same as in C#:

using (StreamReader reader = File.OpenText("hello.txt")) {
    // code 
}

A separate keyword like in C#, instead of if would be better, of course.

With a macro, similar to C# syntax:

#define Using(what) if(what; true)

Using(std::ofstream myfile("hello.txt")) {
        // code 
};

Requires C++ 17.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文