Thanks for your reply. Indeed i'm using extend now.. it was one of my
possible design, and i was assessing all possible cases.
I have come to this design. And i have a question, what is
AddExtension for ?
#File AbstractClass
option optimize_for = SPEED;
message AbstractClass
{
optional int32 AbstractClassInformation = 1;
extensions 100 to 199;
}
#File ConcreteClass
import "AbstractClass.proto";
message ConcreteClass
{
required AbstractClass super = 1;
extend AbstractClass
{
optional ConcreteClass derived_ConcreteClass = 100;
}
}
And using carefully the Extension API, i.e. letting the nested object
or extend part creation to the Extension API, i think
i managed to obtain a double link between the abstract and concrete
objects.
//test to see field manipulation of Abstract Class from Derived Class
void Test_HD_LinkDerivedToAbstract()
{
ConcreteClass * cc = new ConcreteClass();
AbstractClass * ac = cc->mutable_super();
//42...
cc->mutable_super()->set_abstractclassinformation(42);
//yes it does not create another instance
AbstractClass * ac2 = cc->mutable_super();
std::cout << "test on link derived to abstract " << endl;
std::cout << "information from cc instance " << cc->super
().abstractclassinformation() << endl;
std::cout << "information from ac instance " << ac-
>abstractclassinformation() << endl;
std::cout << "information from ac2 instance " << ac2-
>abstractclassinformation() << endl;
}
//test to see field manipulation of Derived Class
void Test_HD_LinkAbstractToDerived()
{
AbstractClass * ac = new AbstractClass();
//Add extension doesn't seem to work and i dunno why?
//ac->AddExtension(ConcreteClass::derived_ConcreteClass);
ConcreteClass * cc = ac->MutableExtension
(ConcreteClass::derived_ConcreteClass);
cc->mutable_super()->set_abstractclassinformation(42);
ConcreteClass * cc2 = ac->MutableExtension
(ConcreteClass::derived_ConcreteClass);
cc2->mutable_super()->set_abstractclassinformation(422);
std::cout << "test on link abstract to derived" << endl;
std::cout << "information from ac instance " << ac-
>abstractclassinformation() << endl;
std::cout << "information from cc instance " << cc->super
().abstractclassinformation() << endl;
std::cout << "information from cc2 instance " << cc2->super
().abstractclassinformation() << endl;
//test ClearExtension OK
//ac->ClearExtension(ConcreteClass::derived_ConcreteClass);
//test HasExtension OK
bool hasExtension = ac->HasExtension
(ConcreteClass::derived_ConcreteClass);
(hasExtension) ? std::cout << "well done ;) \n" : std::cout << "T_T
have to change your design\n";
}
This current design kind of satisfying me, i will try to test it in
the Java generated Classes :) .
cheers,
Pascal Ly.
On May 28, 8:44 pm, Kenton Varda <[email protected]> wrote:
> You can only have mutually-recursive messages if they are defined in the
> same file.
>
> I don't think your approach would work quite as you expect anyway. Message
> fields are not pointers, so you can't have a recursive object at runtime.
> That is, if you do:
>
> message A {
> optional B b = 1;
> }
> message B {
> optional A a = 1;
> }
>
> If you have an instance of A called foo, you *cannot* make it so that
> foo.b.a == foo -- foo.b.a is an entirely different object.
>
> If you need to be able to down-cast (that is, given a pointer to the
> superclass, you need a way to get a pointer to the subclass), then you need
> the superclass to look like:
>
> message Superclass {
> // One of the following will be filled in.
> optional Subclass1 subclass1 = 1;
> optional Subclass2 subclass2 = 2;
> ...
> }
>
> You can use extensions instead of normal fields, which is often useful for
> these cases. Other than that, though, there's no other option. You cannot
> convert a Subclass1 back to a Superclass, so you have to pass around
> pointers to the Superclass itself and simply say "This object must contain a
> subclass1".
>
> In general, you may find that trying to shoe-horn a concept of inheritance
> into protocol buffers doesn't work well. Unfortunately, classic
> object-oriented inheritance does not translate well to message formats sent
> over the wire. Extensions, on the other hand, are very straightforward on
> the wire, which is why that is what protocol buffers provides.
>
>
>
> On Thu, May 28, 2009 at 10:16 AM, <[email protected]> wrote:
>
> > Just to complete the view, i' m trying to simulate inheritance.
>
> > Derived Classes need to have a required field to their mother (so that
> > when i'm using directly a derived class i can set the super class
> > fields).
>
> > And abstract classes need to have an optional field
> > to all possible derived classes (emulate the fact that a super class
> > can become any sort of derived class).
>
> > I can bypass the problem by using "extend" in the derived classes
> > message file (extending field of the super class, adding an optional
> > field of themselves) , so that only the derived classes side need to
> > use import.
>
> > but i was wondering if there was another way to do so ??
>
> > cheers,
>
> > Pascal ly
>
> > On May 28, 6:51 pm, [email protected] wrote:
> > > Hi,
>
> > > i need a message A to have a field with a message B, and at the same
> > > time i need messages B to have a field to message A, how to avoid
> > > recursive imports ??
>
> > > cheers,
>
> > > Pascal Ly.- Hide quoted text -
>
> - Show quoted text -
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Protocol Buffers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/protobuf?hl=en
-~----------~----~----~----~------~----~------~--~---