如何知道C+中所有者对象的地址+;? < P>我想在C++中创建一个通知类,当对象被破坏时,我将用它在其他对象中通知不同的持有者。p> template <class Owner> class Notifier<Owner> { public: Notifier(Owner* owner); ~Notifier(); // Notifies the owner that an object is destroyed }; class Owner; class Owned { public: Owned(Owner* owner); private: Notifier<Owner> _notifier; }; 模板 类通知程序{ 公众: 通知人(所有者*所有者); ~Notifier();//通知所有者对象已销毁 }; 类所有者; 阶级所有{ 公众: 拥有(所有者*所有者); 私人: 通知者(Notifier);; };
我的观点是,由于我有一个密集而复杂的对象图,我希望避免将所拥有对象的地址存储在通知程序中。有没有一种方法可以更改我的通知程序类,以便它可以从自己的地址和编译时计算的偏移量推断出拥有对象的地址 还请注意,任何对象都可能必须通知多个“所有者”,可能来自同一类如何知道C+中所有者对象的地址+;? < P>我想在C++中创建一个通知类,当对象被破坏时,我将用它在其他对象中通知不同的持有者。p> template <class Owner> class Notifier<Owner> { public: Notifier(Owner* owner); ~Notifier(); // Notifies the owner that an object is destroyed }; class Owner; class Owned { public: Owned(Owner* owner); private: Notifier<Owner> _notifier; }; 模板 类通知程序{ 公众: 通知人(所有者*所有者); ~Notifier();//通知所有者对象已销毁 }; 类所有者; 阶级所有{ 公众: 拥有(所有者*所有者); 私人: 通知者(Notifier);; };,c++,templates,notifications,one-to-many,C++,Templates,Notifications,One To Many,我的观点是,由于我有一个密集而复杂的对象图,我希望避免将所拥有对象的地址存储在通知程序中。有没有一种方法可以更改我的通知程序类,以便它可以从自己的地址和编译时计算的偏移量推断出拥有对象的地址 还请注意,任何对象都可能必须通知多个“所有者”,可能来自同一类 谢谢。解决方案的一部分是从通知程序继承。这样,被销毁对象的地址就是“This” class Owned : public Notifier<Owner> { public: Owned(Owner* owner) :
谢谢。解决方案的一部分是从通知程序继承。这样,被销毁对象的地址就是“This”
class Owned : public Notifier<Owner> {
public:
Owned(Owner* owner)
: Notifier<Owner>(owner)
{}
};
类拥有:公共通知程序{
公众:
拥有(所有者*所有者)
:通知者(所有者)
{}
};
但是如何处理来自同一类的多个“所有者”?如何从“同一类”继承多次
感谢,以下是我一直在寻找的解决方案:
#include <iostream>
template <class Owner, class Owned, int = 0>
class Notifier {
public:
Notifier(Owner* owner)
: _owner(owner)
{}
~Notifier() {
_owner->remove(owned());
}
Owned * owned(){
return static_cast< Owned * >( this );
}
private:
Owner* _owner;
};
class Owner {
public:
void remove(void* any) {
std::cout << any << std::endl;
}
};
class Owned : public Notifier<Owner,Owned,1>, Notifier<Owner,Owned,2> {
public:
Owned(Owner* owner1, Owner* owner2)
: Notifier<Owner,Owned,1>(owner1)
, Notifier<Owner,Owned,2>(owner2)
{}
};
int main() {
std::cout << sizeof(Owned) << std::endl;
Owner owner1;
Owner owner2;
Owned owned(&owner1, &owner2);
std::cout << "Owned:" << (void*)&owned << std::endl << std::endl;
}
#包括
模板
类通知程序{
公众:
通知程序(所有者*所有者)
:_所有者(所有者)
{}
~Notifier(){
_所有者->删除(owned());
}
Owned*Owned(){
返回静态_cast(此);
}
私人:
业主*\业主;
};
类所有者{
公众:
作废删除(作废*任何){
std::cout看一看。我非常怀疑。通知者无法知道它已被用于作文中。如果我知道呢
class Foo
{
private:
Notifier _a, _b, _c;
}
虽然我很想被证明是错误的,但我真的怀疑如果不明确地向通知者提供更多信息,它是否可行。这将是一个令人讨厌的黑客攻击,可能无法保证有效,但这里有一个想法我不建议这样做
假设您有如下描述的布局:
template <class Owner>
class Notifier<Owner> {
public:
Notifier(Owner* owner);
~Notifier(); // Notifies the owner that an object is destroyed
};
class Owner;
class Owned {
public:
Owned(Owner* owner);
private:
Notifier<Owner> _notifier;
};
基本上,假设_notifier在拥有的类中处于某个固定的偏移量。因此,拥有的地址等于
_notifier的地址减去相同的偏移量
再一次,这是一种未定义的行为,我不推荐,但可能会起作用。或类似的内容: 从您的通知程序继承并添加Owned as template参数。然后,您可以在通知程序中使用Owned方法:
template < class Owner , class Owned >
class Notifier
{
public:
Notifier(Owner* owner)
{}
Owned * owned()
{ return static_cast< Owned * >( this ); }
~Notifier()
{
// notify owner with owned()
}
};
class Owner
{};
class Owned : public Notifier< Owner , Owned >
{
public:
Owned( Owner * owner ) : Notifier< Owner , Owned >( owner )
{}
};
模板
类通知程序
{
公众:
通知程序(所有者*所有者)
{}
拥有*拥有()
{返回静态_cast(this);}
~Notifier()
{
//通知拥有者()
}
};
类所有者
{};
拥有类别:公共通知程序<所有者,拥有>
{
公众:
拥有者(所有者*所有者):通知者<所有者,拥有者>(所有者)
{}
};
是一个良好的开端。但是,它并不能解决同一类型的多个所有者的问题。一种解决方案是让通知程序存储所有者列表,而不是单个所有者。下面是一个快速实现,以展示这一想法:
template <typename Owner, typename Owned>
class Notifier
{
protected:
Notifier()
{}
// Constructor taking a single owner
Notifier(Owner & o)
{
owners.push_back(&o);
}
// Constructor taking a range of owners
template <typename InputIterator>
Notifier(InputIterator firstOwner, InputIterator lastOwner)
: owners(firstOwner, lastOwner) {}
~Notifier()
{
OwnerList::const_iterator it = owners.begin();
OwnerList::const_iterator end = owners.end();
for ( ; it != end ; ++it)
{
(*it)->notify(static_cast<Owned*>(this));
}
}
// Method for adding a new owner
void addOwner(Owner & o)
{
owners.push_back(&o);
}
private:
typedef std::vector<Owner *> OwnerList;
OwnerList owners;
};
模板
类通知程序
{
受保护的:
通知程序()
{}
//拥有单一所有者的构造函数
通知程序(所有者和运营商)
{
所有者。推回(&o);
}
//一系列拥有者
模板
通知程序(InputIterator firstOwner、InputIterator lastOwner)
:所有者(第一所有者,最后所有者){}
~Notifier()
{
OwnerList::const_iterator it=owners.begin();
OwnerList::const_iterator end=owners.end();
for(;it!=end;++it)
{
(*it)->通知(静态_cast(this));
}
}
//用于添加新所有者的方法
void addOwner(所有者和运营商)
{
所有者。推回(&o);
}
私人:
typedef std::向量所有者列表;
业主主义业主;
};
您可以这样使用它:
class Owner;
class Owned : public Notifier<Owner, Owned>
{
typedef Notifier<Owner, Owned> base;
//Some possible constructors:
Owned(Owner & o) : base(o) { }
Owned(Owner & o1, Owner & o2)
{
base::addOwner(o1); //qualified call of base::addOwner
base::addOwner(o2); //in case there are other bases
}
Owned(std::list<Owner*> lo) : base(lo.begin(), lo.end()) { }
};
类所有者;
类拥有:公共通知程序
{
typedef通知程序库;
//一些可能的构造器:
拥有(所有者和运营商):基地(运营商){}
拥有(所有者和o1、所有者和o2)
{
base::addOwner(o1);//base::addOwner的限定调用
base::addOwner(o2);//如果还有其他的base
}
拥有(std::list lo):基(lo.begin(),lo.end()){
};
如果您有许多不同类型的所有者,则此解决方案可能会变得非常难以使用。在这种情况下,您可能需要查看boost元编程库(,),使用这些库,您可以得到一段代码,让您可以执行以下操作:
class Owned : public Notifier<Owned, OwnerType1, OwnerType1, OwnerType2>
{
Owned(OwnerType1 & o1, OwnerType1 & o2, OwnerType2 & o3)
: base(o1,o2,o3)
};
类拥有:公共通知程序
{
自有(所有者类型1和o1、所有者类型1和o2、所有者类型2和o3)
:碱(o1、o2、o3)
};
但是,实现此解决方案比上一个要长一点。我确实在寻找一种实现一对多关系的方法。它可以很好地用于观察者模式,但不一定。@Xavier:我不确定我是否理解您的意思。“非常好地用于观察者”.Observer是实现通知的方式。“Observer定义了一个一对多的关系,这样当一个对象更改状态时,其他对象将被自动通知和更新”。但我希望多个对象通知一个对象(以节省内存的方式)。任何模板(或其他)在编译时提供此信息的诀窍?模板在这里无法帮助您。您需要静态多态性还是可以使用纯虚拟方法“notify”创建抽象基类IOOwner?不,我不能使用纯虚拟的“notify”。在通知程序中,您不能存储所有者列表而不是单个所有者吗?您的用例确实是让您在编译时了解所有这些?并且您对实例化这么多模板的代码膨胀没有意见?用例是在业务对象模型中实现类之间的关系。例如,需求链接到客户:我知道所有关于
class Owned : public Notifier<Owned, OwnerType1, OwnerType1, OwnerType2>
{
Owned(OwnerType1 & o1, OwnerType1 & o2, OwnerType2 & o3)
: base(o1,o2,o3)
};