Re: to_derived virtual member function
On Mar 10, 7:48 pm, Ulrich Eckhardt <ulrich.eckha...@dominolaser.com>
wrote:
Anyhow, you are then back to pretty much the
same syntax as a dynamic cast.
The problem does not occur in objective-c and I don't think it is
caused by the static typing of C++. Dynamic casts could be performed
by the compiler in the sense
that it could automatically insert a "dummy" virtual function in the
base class when a new derived class introduces a new virtual
function.
Since dynamic_casts cannot be used by the derived objects, I don't see
any other solution than to use the following base class (for values)
with ALL functions added and a smart pointer
to remove the burden of deletion (ptr is a reference-counted smart
pointer):
#pragma once
/* Macros to declare a value */
#define declare(V,T,N) basicvalue::value V=new T(N)
#define declareinclass(V) basicvalue::value V
#include <cassert>
#include <fstream>
#include <sstream>
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <cstring>
#include "utils.hpp"
using namespace std;
/*
* basicvalue type
*/
struct basicvalue
{
protected:
virtual void bout(fstream&){}
virtual void bin(fstream&){}
public:
string name;
typedef ptr<basicvalue> value;
friend ostream& operator<<(ostream&out,basicvalue& rhs)
{
out<<rhs.name<<endl;
rhs.stream_out(out);
return(out);
}
friend istream& operator>>(istream&inp,basicvalue& rhs)
{
inp>>rhs.name;
rhs.stream_in(inp);
return(inp);
}
void binary_out(fstream& os)
{
write(os,name);
bout(os);
}
void binary_in(fstream& is)
{
read(is,name);
bin(is);
}
// Update this part as soon as new derived types are created
/* This part lists the atribution operators for each derived
struct */
virtual void operator=(const int&){}
virtual void operator=(const string&){}
virtual void operator=(const double&){}
virtual void operator=(const bool&){}
virtual void operator=(char*){}
virtual void operator=(const vector<value >&){}
/* Push stuff into vectors */
virtual void push(const value&){}
/* Gets stuff from vectors */
virtual basicvalue& get(const string&){return *this;}
/* Returns the size of vectors */
virtual int size(){return(0);}
/* Cloning operation */
virtual basicvalue* clone(){return new basicvalue;}
/* This part lists the cast operators */
virtual operator int(){return int();}
virtual operator double(){return double();}
virtual operator string(){return string();}
virtual operator bool(){return bool();}
virtual operator vector<value>(){return(vector<value>());}
/* Basic IO functions */
virtual void stream_out(ostream&){}
virtual void stream_in(istream&){}
virtual ~basicvalue()
{
name.clear();
}
basicvalue(const string& othername=""):name(othername){}
};
struct Integer:basicvalue
{
private:
int data;
public:
Integer(const string& othername=""):data(0),basicvalue(othername)
{}
basicvalue* clone()
{
basicvalue* tmp=new Integer(name);
*tmp=data;
return(tmp);
}
void operator=(const int& d)
{
data=d;
}
operator int()
{
return(data);
}
void stream_out(ostream & os)
{
os<<data;
}
void stream_in(istream & is)
{
is>>data;
}
protected:
void bout(fstream& os)
{
write(os,data);
}
void bin(fstream& is)
{
read(is,data);
}
};
.......
struct Vector:basicvalue
{
private:
map<string,value> data;
public:
Vector(const string& othername=""):data(map<string,value
()),basicvalue(othername){}
basicvalue* clone()
{
Vector* tmp=new Vector(name);
tmp->data=data;
return(tmp);
}
void operator=(const vector<value>& d)
{
data.clear ();
for(vector<value>::const_iterator it=d.begin ();it!=d.end ();+
+it)
data[(*it)->name]=*it;
}
void push(const value& d)
{
data[d->name]=d;
}
basicvalue& get(const string& othername)
{
return(*data[othername]);
};
int size()
{
return(data.size ());
}
operator map<string,value>()
{
return(data);
}
void stream_out(ostream & os)
{
os<<data.size()<<endl;
for(map<string,value>::iterator it=data.begin();it!=data.end();
++it)
os<<*(it->second)<<endl;
}
void stream_in(istream & is)
{
size_t temp;
is>>temp;
if(temp!=data.size())cerr<<"Wrong reading"<<endl;
for(map<string,value>::iterator it=data.begin();it!=data.end();
++it)
is>>*(it->second);
}
~Vector()
{
data.clear ();
}
protected:
void bout(fstream & os)
{
size_t dim=data.size();
write(os,dim);
for(map<string,value>::iterator it=data.begin();it!=data.end();
++it)
(it->second)->binary_out(os);
}
void bin(fstream & is)
{
size_t temp;
read(is,temp);
if(temp!=data.size())cerr<<"Wrong reading"<<endl;
for(map<string,value>::iterator it=data.begin();it!=data.end();
++it)
(it->second)->binary_in(is);
}
};
Now the problem is the maintenance of the base class. Every time a new
derived class is added, new functions must be appended. ALL this
because C++ wants the programmer to "feel" the cost of a cast
everytime one is needed.
Am I missing something?
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]