在 sfml 中为派生 类 初始化一次纹理
Initialize texture once for derived classes in sfml
最近,我尝试用纹理练习 SFML。但是,我遇到了一些问题。 SFML 网站告诉我,使用纹理最有效的方法是更新精灵。否则,我们的程序可能会消耗大量内存。我有一个基础 class 和另外两个 class 派生自它。我如何初始化我的 texture
变量,以便派生的 classes 可以将它用于他们的精灵?我已经尝试在 Base
class 构造函数中初始化纹理并在派生的 classes 中调用它,但是后来,我意识到我的问题没有解决,因为调用一个构造函数两次是一个废话。这个问题对我来说非常重要,因为我正在使用创建大量动态分配对象的状态模式。
#include <iostream>
class Base
{
protected:
sf::Texture texture; //How to initialize this?
sf::Sprite sprite;
public:
Base();
};
class Derived1 : public Base
{
public:
Derived1()
{
sprite.setTexture(texture);
}
};
class Derived2 : public Base
{
public:
Derived2()
{
sprite.setTexture(texture);
}
};
享元模式
SFML website tells me that the most efficient way to use textures is to update sprites. Otherwise, our program may consume a lot of memory.
是的,sf::Sprite
和sf::Texture
的关系对应的是The Flyweight Pattern,一种结构化设计模式。
sf::Texture
是一种重量级 对象,我们希望尽可能共享其数据以节省内存。一个sf::Sprite
是一个享元对象,多个sf::Sprite
对象可以引用同一个sf::Texture
对象来共享它的数据。
sf::Sprite
只包含特定于它所引用的纹理的特定用途的信息,例如纹理的位置、旋转、大小——这是 外部的状态。 sf::Texture
对象包含可以由多个 sf::Sprite
对象共享的数据(即纹理图像本身)——这是由所有对象共享的 内在状态 引用相同 sf::Texture
.
的 sf::Sprite
个对象
在 SFML 库中,您还可以找到带有 sf::Text
/sf::Font
和 sf::Sound
/sf::SoundBuffer
的这种模式。
不放弃享元
牢记上面公开的模式,您可能还想在设计中遵循它:
class Base {
public:
Base(const sf::Texture& texture): sprite(texture) {}
protected:
sf::Sprite sprite;
};
class Derived: public Base {
public:
Derived(const sf::Texture& texture): Base(texture) {}
// ...
};
sprite
数据成员通过sf::Texture
初始化,通过引用传递给构造函数,多个Base
和Derived
对象可以共享同一个sf::Texture
.
举个例子:
sf::Texture myTexture;
myTexture.loadFromFile("myImageFile.png");
Base b1(myTexture), b2(myTexture);
Derived d1(myTexture), d2(myTexture);
b1
、b2
、d1
和 d2
都共享同一个 sf::Texture
实例 – myTexture
:
当然,none 这些对象的寿命应该比 myTexture
长。
最近,我尝试用纹理练习 SFML。但是,我遇到了一些问题。 SFML 网站告诉我,使用纹理最有效的方法是更新精灵。否则,我们的程序可能会消耗大量内存。我有一个基础 class 和另外两个 class 派生自它。我如何初始化我的 texture
变量,以便派生的 classes 可以将它用于他们的精灵?我已经尝试在 Base
class 构造函数中初始化纹理并在派生的 classes 中调用它,但是后来,我意识到我的问题没有解决,因为调用一个构造函数两次是一个废话。这个问题对我来说非常重要,因为我正在使用创建大量动态分配对象的状态模式。
#include <iostream>
class Base
{
protected:
sf::Texture texture; //How to initialize this?
sf::Sprite sprite;
public:
Base();
};
class Derived1 : public Base
{
public:
Derived1()
{
sprite.setTexture(texture);
}
};
class Derived2 : public Base
{
public:
Derived2()
{
sprite.setTexture(texture);
}
};
享元模式
SFML website tells me that the most efficient way to use textures is to update sprites. Otherwise, our program may consume a lot of memory.
是的,sf::Sprite
和sf::Texture
的关系对应的是The Flyweight Pattern,一种结构化设计模式。
sf::Texture
是一种重量级 对象,我们希望尽可能共享其数据以节省内存。一个sf::Sprite
是一个享元对象,多个sf::Sprite
对象可以引用同一个sf::Texture
对象来共享它的数据。
sf::Sprite
只包含特定于它所引用的纹理的特定用途的信息,例如纹理的位置、旋转、大小——这是 外部的状态。 sf::Texture
对象包含可以由多个 sf::Sprite
对象共享的数据(即纹理图像本身)——这是由所有对象共享的 内在状态 引用相同 sf::Texture
.
sf::Sprite
个对象
在 SFML 库中,您还可以找到带有 sf::Text
/sf::Font
和 sf::Sound
/sf::SoundBuffer
的这种模式。
不放弃享元
牢记上面公开的模式,您可能还想在设计中遵循它:
class Base {
public:
Base(const sf::Texture& texture): sprite(texture) {}
protected:
sf::Sprite sprite;
};
class Derived: public Base {
public:
Derived(const sf::Texture& texture): Base(texture) {}
// ...
};
sprite
数据成员通过sf::Texture
初始化,通过引用传递给构造函数,多个Base
和Derived
对象可以共享同一个sf::Texture
.
举个例子:
sf::Texture myTexture;
myTexture.loadFromFile("myImageFile.png");
Base b1(myTexture), b2(myTexture);
Derived d1(myTexture), d2(myTexture);
b1
、b2
、d1
和 d2
都共享同一个 sf::Texture
实例 – myTexture
:
当然,none 这些对象的寿命应该比 myTexture
长。