当我们在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); \
这是不可能的。有什么办法可以做到这一点?
答案 0 :(得分:5)
首先,您的代码甚至无法编译。这是固定版本:
#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
技巧。
这几乎总是一种不好的做法,当然在您的情况下也是如此。
答案 1 :(得分:2)
当我们在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;
}
}
但是您应该避免使用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();
}
}
答案 2 :(得分:1)
更改#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);
// ...
}