但可惜一個 friend 宣告只會對一個類別產生作用:
class Texture {
public:
friend class IResourceLoader;
uint width() const { return mWidth; }
uint height() const { return mHeight; }
private:
uint mWidth;
uint mHeight;
};
class IResourceLoader {};
class JpegLoader : public IResourceLoader {
void load() {
// ...
mTexture.mWidth = 128; // Compiler error!!
}
};
以上的 Texture 類別有成員 mWidth 和 mHeight, 它們都只應由 IResourceLoader 的實作類別所能更改. 幸好有 Inner class 可以幫到我們:
// Texture.h
class Texture {
public:
friend class IResourceLoader;
uint width() const { return mWidth; }
uint height() const { return mHeight; }
// We declare a templated inner class here (but not defined yet)
templateclass PrivateAccessor;
private:
uint mWidth;
uint mHeight;
};
class IResourceLoader {};
// JpegLoader.cpp
// Define Texture::PrivateAccessor here, access what ever you want
template<>
class Texture::PrivateAccessor{
public:
static size_t& width(Texture& texture) {
return texture.mWidth;
}
static size_t& height(Texture& texture) {
return texture.mHeight;
}
};
typedef Texture::PrivateAccessorAccessor;
void JpegLoader::load() {
// ...
Accessor::width(mTexture) = 128; // Ok! no problem
Accessor::height(mTexture) = 128;
}
你可能會認為這樣做等同把所有成員變為公開 (public), 事實上這個方案的精神在於迫使程序員清楚自己正在做什麼, 而不是錯誤地更改了變數.
沒有留言:
發佈留言