Re: Returning an unknown number of types/values

From: Jumbo (nospam)
Date: 01/16/04


Date: Fri, 16 Jan 2004 22:30:20 -0000


"Tony Burrows" <tony@tonyburrows.com> wrote in message
news:pan.2004.01.15.09.51.54.364880@tonyburrows.com...
> Thanks for all the help! I'll try some of these.
>
> I had actually got to the idea of vector< vector< tObject *> > where my
> tObject is your Base, but I'd subclassed to all the possibilities and then
> had to use a dynamic cast when getting the value back. Overloading get is
> so much better.
>
> I'd never heard of boost, now to investigate that.
>
Perhaps my code will make it clearer what I am trying to explain:

#include <iostream>
#include <string>
#include <vector>

using std::cout;

class Base{
public:
 virtual ~Base()=0{}
 virtual void setData(int){}
 virtual void setData(double){}
 virtual void setData(std::string){}
 //virtual void setData(){}
};

class Variant{
public:
 Variant():itsArray(0),itsLen(0){}
 Variant(const std::vector<std::string> &v1)
 :itsArray(new Base*[v1.size()]),
 itsLen(v1.size()),
 itsTypes(v1){
  for(size_t i=0;i<v1.size();i++){
  if(v1[i]=="int")itsArray[i] = new DataType<int>;
  else if(v1[i]=="double")itsArray[i] = new DataType<double>;
  else if(v1[i]=="std::string")itsArray[i] = new DataType<std::string>;
  else itsArray[i] = 0;
  }
  //itsArray[3]->setData();??
 }
 ~Variant(){
  for(size_t i=0;i<itsLen;i++){delete itsArray[i];}
  delete itsArray;
 }
 size_t getLen()const{return itsLen;}

 Variant(const Variant& rhs):itsLen(rhs.getLen()),itsArray(new
Base*[itsLen]){
  for(size_t i=0;i<itsLen;i++){
   if( rhs.itsTypes[i]=="int")itsArray[i] = new DataType<int>;
   else if(rhs.itsTypes[i]=="double")itsArray[i] = new DataType<double>;
   else if(rhs.itsTypes[i]=="std::string")itsArray[i] = new
DataType<std::string>;
  else itsArray[i] = 0;
  }
 }
 Variant& operator=(const Variant& rhs){
  itsLen = rhs.getLen();
  itsArray = new Base*[itsLen];
  for(size_t i=0;i<itsLen;i++){
   if( rhs.itsTypes[i]=="int")itsArray[i] = new DataType<int>;
   else if(rhs.itsTypes[i]=="double")itsArray[i] = new DataType<double>;
   else if(rhs.itsTypes[i]=="std::string")itsArray[i] = new
DataType<std::string>;
   else itsArray[i] = 0;
  }
  return *this;
 }
private:
 std::vector<std::string> itsTypes;
 size_t itsLen;
 Base** itsArray;

 template<typename T>
 class DataType: public Base{
 public:
  DataType():data(0){cout<<"Default DataType constructor"<<'\n';}
  ~DataType(){cout<<"DataType dest..."<<'\n';}
  void setData(){cout<<"setting data for type: "<<typeid(T).name()<<'\n';}
 private:
  T data;
 };
};

/* Specialize any types you don't want initialised to 0 */
/* Specialized std::string constructor */
template<>
Variant::DataType<std::string>::DataType():data("0"){
 cout<<"DataType const with std::string"<<'\n';
}

int main(){

 std::vector<std::string> strArr1(4);
 strArr1[0] = "int";
 strArr1[1] = "std::string";
 strArr1[2] = "double";
 strArr1[3] = "jtd::jing"; /*deliberate error*/

 std::vector<std::string> strArr2(3);
 strArr2[0] = "std::string";
 strArr2[1] = "std::string";
 strArr2[2] = "double";

 Variant v1(strArr1); /*Will have 4 Datatypes, one will be null.*/
 Variant v2(strArr2); /*Will have 3 Datatypes.*/

 std::vector<Variant> vv(2);
 vv[0] = v1;
 vv[1] = v2;
// etc etc....
return 0;
}

This class works with vectors and I am currently looking into how it works
with iterators, algorithms and maps and I think I can make it fully
compatable with the complete standard library.
I haven't posted it with accessor functions etc as I don't know what you
need. Do you want to initialise the Variant DataTypes with a array of
strings or do you want to initialise each piece of data individually and how
do you want to access the data etc. I have included a basic foundation for
setter functions and from this it should be easy to understand how to
implement any type of accessor methods.

HTH.

Note : You may encounter problems if you think you can overload the
subscript( [] )operator to return a particular index because this would mean
the function only differs return type, which I don't think is allowed in
function overloading(please correct me if I am wrong). However think I may
have worked out a way in which this can be done but I have yet to test it.



Relevant Pages

  • completed my Varaint class.
    ... I have completed the variant class I have been working on and I wonder if ... virtual void setData ... Variant(const Variant& rhs); ...
    (alt.comp.lang.learn.c-cpp)
  • Re: completed my Varaint class.
    ... >> I have completed the variant class I have been working on and I wonder ... crap so I am looking into using overloaded template constructors to create ... had supplied an invlaid string parameter, then a null index is created. ... But there's no other way to initialise different types except if the type ...
    (alt.comp.lang.learn.c-cpp)
  • Re: ExecWB and VARIANT
    ... I tried to get it to save without the SaveAs dialog and I ... I don't know how to initialise the VARIANT* pvaIn variable to store ... the OK button the program does not return from the ExecWB method, ...
    (microsoft.public.vc.mfc)
  • Re: ExecWB and VARIANT
    ... I don't know how to initialise the VARIANT* pvaIn variable to store ... the OK button the program does not return from the ExecWB method, ... What i want is that ExecWB saves the webpage NOT displaying a SaveAs ...
    (microsoft.public.vc.mfc)
  • Re: ExecWB and VARIANT
    ... because the SaveAs dialog will come up anyway. ... void CWebBrowser2::ExecWB(long cmdID, long cmdexecopt, VARIANT* pvaIn, ... I want to SaveAs a webpage using the cmdID = IDM_SAVEAS. ... I don't know how to initialise the VARIANT* pvaIn variable to store ...
    (microsoft.public.vc.mfc)