std::函数成员可以访问其他成员吗? 我正在制作一个小型的塔防游戏,以练习C++。我知道其他语言,但在C++中几乎没有什么实际开发。 在这个游戏中,我将有几个建筑,所以我制作了一个类似这样的类: class Building { private: sf::Sprite& sprite; float timer = 0; void update(float delta); };
现在,我会有很多不同的建筑,但它们都应该有相同的成员。现在,在Java中,我将(必须)为每种不同类型的建筑创建一个子类,但我在想,我可以更改std::函数成员可以访问其他成员吗? 我正在制作一个小型的塔防游戏,以练习C++。我知道其他语言,但在C++中几乎没有什么实际开发。 在这个游戏中,我将有几个建筑,所以我制作了一个类似这样的类: class Building { private: sf::Sprite& sprite; float timer = 0; void update(float delta); };,c++,c++11,lambda,C++,C++11,Lambda,现在,我会有很多不同的建筑,但它们都应该有相同的成员。现在,在Java中,我将(必须)为每种不同类型的建筑创建一个子类,但我在想,我可以更改void update(float delta)到std::函数更新并具有创建不同建筑的工厂功能?我想象的是这样的: 在h楼: class Building { private: sf::Sprite& sprite; float timer = 0; std::function<void(float)> upda
void update(float delta)代码>到std::函数更新代码>并具有创建不同建筑的工厂功能?我想象的是这样的:
在h楼:
class Building
{
private:
sf::Sprite& sprite;
float timer = 0;
std::function<void(float)> update;
};
班级建设
{
私人:
雪碧&雪碧;
浮动计时器=0;
功能更新;
};
和在building.cpp中
Building getBuildingA()
{
Building b;
b.sprite = /* ... */
b.update = [](float delta) {
std::cout << timer++ << std::endl;
};
return b;
}
Building-getBuildingA()
{
b楼;
b、 雪碧=/**/
b、 更新=[](浮点增量){
std::cout您可以将lambda捕获设置为this
class Building
{
private:
sf::Sprite& sprite;
float timer = 0;
std::function<void(Building*, float)> update_impl;
void update(float x) { update_impl(this, x); }
};
班级建设
{
私人:
雪碧&雪碧;
浮动计时器=0;
std::函数更新\u impl;
无效更新(float x){update_impl(this,x);}
};
但实际上,基于您设计的这一部分,看起来您真的应该使用子类和虚拟函数;这就是它们的用途
function
的典型应用是在传递函数对象时——例如,用一个方法代替编写接口类的Java范例,尤其是在只编写函数或lambda而不是整个对象的设置中
对于对象多态性,子类化和虚拟函数的主要替代方法是使用模板和泛型编程——尽管这主要适用于需要在编译时发生多态性的情况(我认为这不适合您的情况)您可以简单地捕获这一点
例如:
struct S {
auto foo() {
return [this](){ this->bar(); };
}
void bar() { }
};
int main() {
S s;
s.foo()();
}
#include<cassert>
struct S {
auto foo() {
return [timer = timer](){
assert(timer == 42);
};
}
int timer{42};
};
int main() {
S s{};
s.foo()();
}
如果您使用的是C++14,则可以改用初始值设定项列表。
例如:
struct S {
auto foo() {
return [this](){ this->bar(); };
}
void bar() { }
};
int main() {
S s;
s.foo()();
}
#include<cassert>
struct S {
auto foo() {
return [timer = timer](){
assert(timer == 42);
};
}
int timer{42};
};
int main() {
S s{};
s.foo()();
}
#包括
结构{
自动foo(){
返回[timer=timer](){
断言(计时器==42);
};
}
整数计时器{42};
};
int main(){
S{};
s、 foo()();
}
这样,您将获得一个名为timer的副本初始化变量,该变量将在lambda函数体中使用。您可以通过使用Building的静态成员函数来提供factory类来解决隐私问题
您将遇到的第二个问题是,您正在按值返回建筑,因此,除非发生RVO,否则您将不知道要返回的对象的最终地址。您可以通过让“update()”函数将其作为参数传递来解决此问题
#include <iostream>
#include <functional>
class Building {
// C++ classes are private by default
int timer_;
std::function<void(Building*)> update_;
public:
void update() {
update_(this);
}
static Building getBuildingA() {
Building b;
b.timer_ = 42;
b.update_ = [](Building* b) {
b->timer_++;
std::cout << b->timer_ << '\n';
};
}
};
int main() {
Building b = Building::getBuildingA();
b.update();
return 0;
}
#包括
#包括
班级建设{
/C++类默认为私有类
int定时器;
std::函数更新;
公众:
无效更新(){
更新(本);
}
静态建筑getBuildingA(){
b楼;
b、 计时器u42;
b、 更新=[](建筑物*b){
b->timer_uz++;
std::cout timer_uuu通过捕获此
?您不能通过这样的赋值来初始化引用。它必须在初始值设定项列表中初始化。您可以通过使getBuildingA成为Building的静态成员函数来解决隐私问题。回答得好,谢谢。我明白您关于子类化的观点。这里还有其他问题我的设计,但它是为了探索lambdas和类似的东西可以做什么。为了完整性,我还可以想象函数
也适用的设计;我这里没有完整的图片,所以我的部分建议取决于有根据的猜测。啊,我想我特别想尝试函数
是我遗漏的完整图片的相关部分。:)