是否可以将指向未实例化的对象的指针用作C++中的变量?
Is it possible to use a pointer to an uninstantiated object as a variable in C++?
我希望C++类中的属性是来自特定类继承的未实例化类。然后,此类 heirachy 的所有成员都将实现相同的方法,这意味着我可以实例化对象,然后在情况需要时使用该方法。这里有一些代码(不能编译(演示了我的意思:
#include <iostream>
using namespace std;
class Event {
public:
Event() = default;
virtual void go() = 0;
};
class EventA : Event {
public:
EventA() = default;
void go(){
cout << "Running event A"<< endl;
}
};
class EventB : Event {
public:
EventB() = default;
void go(){
cout << "Running event B"<< endl;
}
};
class Situation{
private:
Event* current_event = &EventA; //Problematic code: EventA does not refer to a value
public:
Situation() = default;
void setEvent(Event* event){
current_event = event;
}
void runEvent(){
current_event.go();
}
};
int main() {
Situation situation;
situation.runEvent();
situation.setEvent(&EventB);
situation.runEvent();
return 0;
};
不,不能形成指向类的指针,也不能在没有类实例(对象(的情况下调用 [非静态] 成员函数。
您可能应该std::make_unique
要使用的类型的实例。
不要忘记给你的基础一个虚拟析构函数,因为你正在做多态的事情。
静态替代方案是std::variant
.
在两个地方,您似乎正在做可以描述为尝试从类型中获取指针的操作:
Event* current_event = &EventA;
和
situation.setEvent(&EventB);
这是行不通的,在C++中并不是一件真正具有正确含义的事情。您正在尝试做的事情可以通过我能想到的 3 种不同方式实现。
方法 1:可以有一个函数指针,而不是一个类,并将函数指针作为参数传递:
#include <iostream>
using namespace std;
void eventA_go(){
cout << "Running event A"<< endl;
}
void eventB_go(){
cout << "Running event B"<< endl;
}
class Situation{
private:
using EventFunctionPtr = void (*)();
EventFunctionPtr current_event = &eventA_go;
public:
Situation() = default;
void setEvent(EventFunctionPtr event){
current_event = event;
}
void runEvent(){
current_event();
}
};
int main() {
Situation situation;
situation.runEvent();
situation.setEvent(&eventB_go);
situation.runEvent();
return 0;
};
方法 2:您可以通过在Situation
类中允许任何类型的可调用对象(而不仅仅是函数指针(来使此代码更加通用:
#include <iostream>
#include <functional>
using namespace std;
void eventA_go(){
cout << "Running event A"<< endl;
}
void eventB_go(){
cout << "Running event B"<< endl;
}
class Situation{
private:
std::function<void ()> current_event = eventA_go;
public:
Situation() = default;
template <typename F>
void setEvent(F&& event){
current_event = event;
}
void runEvent(){
current_event();
}
};
int main() {
Situation situation;
situation.runEvent();
situation.setEvent(&eventB_go);
situation.runEvent();
return 0;
};
方法3:您可以回到最初的想法,即拥有一个必须实现以提供go()
方法的基类,但在这种情况下,您实际上必须确保要调用的对象确实存在。一种可能的方法是使用std::unique_ptr
:
#include <iostream>
#include <memory>
using namespace std;
class Event {
public:
Event() = default;
virtual ~Event() = default;
virtual void go() = 0;
};
class EventA : public Event {
public:
EventA() = default;
void go(){
cout << "Running event A"<< endl;
}
};
class EventB : public Event {
public:
EventB() = default;
void go(){
cout << "Running event B"<< endl;
}
};
class Situation{
private:
std::unique_ptr<Event> current_event = std::make_unique<EventA>();
public:
Situation() = default;
void setEvent(std::unique_ptr<Event>&& event){
current_event = std::move(event);
}
void runEvent(){
current_event->go();
}
};
int main() {
Situation situation;
situation.runEvent();
situation.setEvent(std::make_unique<EventB>());
situation.runEvent();
return 0;
};
请注意,在这种情况下,抽象类的析构函数必须是virtual
的,并且继承必须是公共的。
您似乎对类和变量感到困惑。situation.runEvent();
哪个对象上运行?我认为您想从Event
公开派生类并在需要时初始化current_event
。你不需要做任何像current_event = &EventB
.C++根据动态指向的内容自动确定需要调用current_event
函数。以下是我认为你的意思:
#include <cassert>
#include <iostream>
class Event {
public:
virtual void go() = 0;
virtual ~Event() = default; // Don't forget the virtual destructor
};
class EventA : public Event {
public:
void go() override { std::cout << "Running event A" << std::endl; }
};
class EventB : public Event {
public:
void go() override { std::cout << "Running event B" << std::endl; }
};
class Situation {
private:
Event* current_event = nullptr;
public:
void setEvent(Event* event) { current_event = event; }
void runEvent() {
assert(current_event);
current_event->go();
}
};
int main() {
Situation situation;
EventA a;
EventB b;
situation.setEvent(&a);
situation.runEvent();
situation.setEvent(&b);
situation.runEvent();
}
- 1d 智能指针不适用于语法 (*)++
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 为什么使用 "this" 指针调用派生成员函数?
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用指针从C++中的数组中获取最大值
- 助记符和指向成员语法的指针
- 嵌入方指针压缩已禁用
- 数组的指针从不分段故障
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 何时在引用或唯一指针上使用移动语义
- QMetaObject invokeMethod的基于函数指针的语法
- 如何从 std::atomic 中提取指针 T<T>?
- 如何在 C# 中映射双 C 结构指针?
- C++将浮点指针值舍入为小数位数
- 为什么++(*p)更改指针值
- 调整大小后指向元素值的指针unordered_map有效?
- 正在将指针转换为范围
- 使用指向成员的指针将成员函数作为参数传递
- 将OpenCV C++重写为EmguCV C#-如何使用指针
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错