Yes, as long as you are using references you are fine (... well not really, see below ...). You can call virtual methods through references
that's what I mean - use references, I think I am fine, see below.
and you can cast them back to references to the appropriate child-class of basic. However, at some point you will need to create real objects. This is because writing basic &e = power(a+b, 2) is not allowed. The compiler will reject it. It would create a reference out of a temporary which you cannot do in C++. Oh well, I said that you will need to create real objects, so let us write: basic e = power(a+b, 2) No! Also not good! It will create a new basic object with only the basic-parts of the power. Not the base and exponent.
The problem that he compiler rejects references to temporaries is going to hunt you. The signature of the power constructor cannot be power::power(basic &b, basic &e) because you cannot pass a+b to the first (reference!) argument of the constructor. What shall we do then? Leave out the &'s. No! this will discard all the add-specific data of a+b and only copy the, ehhm well, bare basics.
The point is that your Python data types are already doing for you automatically what GiNaCs exes are doing in C++: being a reference to a garbage-collected data type. I don't think it is possible to do without that.
I am not sure I understand. Why cannot we use it like in the following example? I compiled it and it works as expected: #include <iostream> class basic { public: basic() {}; }; class power:public basic { public: power(basic *a, basic *b) { this->a=a; this->b=b; }; void print() { std::cout<<this->a << " ^ " << this->b << std::endl; } private: //a ... base, b... exponent basic *a,*b; }; basic* pow(basic*a, basic*b) { return new power(a,b); } int main() { basic *e1=new basic(); //some complicated expression basic *e2=new basic(); //some complicated expression basic *p=new power(e1,e2); //p->print(); //this line won't compile in C++, in python its ok ((power *)p)->print(); //OK, prints: 0x804a008 ^ 0x804a018 //because there is no operator for power in C++ to be overloaded, we can create a //function to do that basic *q=pow(e2,e1); ((power *)q)->print(); //OK, prints: 0x804a018 ^ 0x804a008 return 0; } Ondrej