如何避免#define 语法的变量重新声明?
How can I avoid variable re-declaration for #define syntax?
当我们在c++中传递class类型的参数时,我们不得不使用#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
技巧。
这几乎总是不好的做法,当然在你的情况下也是如此。
将#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);
// ...
}
When we pass parameter of class type in c++, we have no choice but to use #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;
}
}
但是你应该避免使用 new
和 delete
运算符,而只使用智能指针:
#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();
}
}
当我们在c++中传递class类型的参数时,我们不得不使用#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
技巧。
这几乎总是不好的做法,当然在你的情况下也是如此。
将#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);
// ...
}
When we pass parameter of class type in c++, we have no choice but to use #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;
}
}
但是你应该避免使用 new
和 delete
运算符,而只使用智能指针:
#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();
}
}