簡體   English   中英

如何避免對#define語法進行變量重新聲明?

[英]How can I avoid variable re-declaration for #define syntax?

當我們在c ++中傳遞類類型的參數時,我們別無選擇,只能使用#define。 但這會使代碼混亂。

#include <vector>
#define APPEND(className) \
        base = new className(); \
        baseVector.push_back(base); \

class Base{};
class Child1 : public Base{};
class Child2 : public Base{};
// ...
class Child10 : public Base{};
std::vector<Base*> baseVector;
int main(void){
    Base* base; // I want to remove this
    APPEND(Child1);
    APPEND(Child2);
    // ...
    APPEND(Child10);
}

如果將Base * base設置為#define語法,則會發生重新聲明錯誤。 但是,如果我順其自然,這看起來很尷尬。

#define APPEND(className) \
        #ifndef DECL \
        Base* base; \
        #define DECL \
        #endif \
        base = new className(); \
        baseVector.push_back(base); \

這是不可能的。 有什么辦法可以做到這一點?

首先,您的代碼甚至無法編譯。 這是固定版本:

#include <vector>

class Base{};

class Child1 : public Base {};
class Child2 : public Base {};

std::vector<Base*> baseVector;

int main(void)
{
    baseVector.push_back( new Child1 );
    baseVector.push_back( new Child2 );

    return 0;
}

您絕對不需要任何#define技巧。 這幾乎總是不正確的做法,當然對於您而言。

當我們在c ++中傳遞類類型的參數時,我們別無選擇,只能使用#define。

我們有選擇。 我們可以使用模板:

#include <vector>
#include <iostream>

using namespace std;

class Base {
public:
    virtual ~Base() {}
    virtual void hello() = 0;
};

class Child1: public Base {
    void hello() { cout << "Child1" << endl; }
};

class Child2: public Base {
    void hello() { cout << "Child2" << endl; }
};

class Child3: public Base {
    void hello() { cout << "Child3" << endl; }
};

vector<Base*> baseVector;

template<typename T>
void append() {
    Base* child = new T{};

    try {
        baseVector.push_back(child);
    } catch (...) {
        delete child;
        throw;
    }
}

int main(void)
{
    append<Child1>();
    append<Child2>();
    append<Child3>();

    for (auto child : baseVector) {
        child->hello();
    }

    for (auto child : baseVector) {
        delete child;
    }
}

但是您應該避免使用newdelete運算符,而只需使用智能指針:

#include <vector>
#include <iostream>
#include <memory>

using namespace std;

class Base {
public:
    virtual ~Base() {}
    virtual void hello() = 0;
};

class Child1: public Base {
    void hello() { cout << "Child1" << endl; }
};

class Child2: public Base {
    void hello() { cout << "Child2" << endl; }
};

class Child3: public Base {
    void hello() { cout << "Child3" << endl; }
};

vector<unique_ptr<Base>> baseVector;

int main(void){
    baseVector.push_back(make_unique<Child1>());
    baseVector.push_back(make_unique<Child2>());
    baseVector.push_back(make_unique<Child3>());

    for (auto& child : baseVector) {
        child->hello();
    }
}

更改#define以將其代碼包裝在自己的方括號中,然后每次調用push_back()時它都可以聲明自己的局部變量。

嘗試更多類似這樣的方法:

#include <vector>

#define APPEND(className) \
{ \
    Base *base = new className(); \
    try { \
        baseVector.push_back(base); \
    } catch (...) { \
        delete base; \
        throw; \
    } \
}

class Base {
public:
    virtual ~Base() {}
};

class Child1 : public Base {};
class Child2 : public Base {};
// ...
class Child10 : public Base {};

std::vector<Base*> baseVector;

int main(void){
    APPEND(Child1);
    APPEND(Child2);
    APPEND(Child3);
    // ...
    APPEND(Child10);
    // ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM