所以我有这个:
class Foo {
public:
Foo(void (*f)(Foo*));
protected:
int x;
};
void function(Foo *foo) {
foo->x = 10;
}
int main () {
Foo bar = Foo(&function);
}
理想情况下,我想通过'function'更改我想要的Foo实例的任何受保护属性。我不知道这样做的任何方法,因为我不能成为该函数的朋友,因为它只是作为参数传递给构造函数。
我可以通过保持相同的结构来实现这一点(我的意思是,通过在创建时使用外部函数来改变Foo的受保护元素)?
我正在编写游戏引擎,其想法是Foo是Room类,用户应该编写自己的函数来将资源加载到Room。所以,我不知道用户的功能名称是什么,因此我不能与它成为朋友。
答案 0 :(得分:1)
1)将x声明为public。
2)在Foo中写一个setter函数来设置x。
3)声明作为朋友的功能,即friend void function(Foo*);
答案 1 :(得分:1)
简短的回答是,您无法向外部函数或类提供对受保护/私有类成员的访问权限,而无需明确授予他们“朋友”访问权。
我提出了一个仍然适合你当前方法/结构的替代方案:
class Room;
struct RoomAssets {
int x;
// ...
};
// Base class for loading Room assets
class AssetLoader {
public:
virtual void loadAssets(RoomAssets *room) = 0;
};
class Room {
public:
Room(AssetLoader *al) {
RoomAssets ra;
al->loadAssets(&ra);
// do what ever you like with the struct values
this->x = ra.x;
}
protected:
int x;
};
// A Room loader that loads 10 of each asset
class TenAssets : public AssetLoader {
public:
void loadAssets(RoomAssets *ra) {
ra->x = 10;
}
};
int main() {
TenAssets da;
Room room(&da);
}
在此示例中,有一个Room类和一个AssetLoader
类。 Room类调用了'{1}}方法,它传递了什么类型的'AssetLoader`。
loadAssets
加载使用值传递的结构,AssetLoader
对象可以随意使用值执行任何操作。
答案 2 :(得分:0)
您可能希望首先提供一个公共setX()函数,然后看看它是如何发生的。
除非绝对必要,否则你会希望避免公开x,例如出于性能原因,如果您在对代码进行分析后确定setX()函数正在减慢速度,那么您只需要执行此操作。
我不确定你能否在这种情况下成为朋友,而你可能也不想这样做。