Avatar billede krismort Nybegynder
23. august 2004 - 23:12 Der er 10 kommentarer

En rigtig hård banan !

Er der en hård banen her som kan hjælpe mig med at se hvad der er galt i den her?

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <windows.h>
#include <stdlib.h>
#include <typeinfo.h>

using namespace std;

class Argument {
private:
   
public: //protected:
    Argument* m_pChild;
    int          m_iLenArg;
    std::string m_strTypeName;

public:

    Argument(void)
        : m_pChild(0)
    {
    }

    //copy construktor
    Argument(const Argument& rhs)
        : m_pChild(0)
    {
    }

    Argument operator << (Argument pChild) {
        setChild(&pChild);
        return *this;
    }

    Argument* operator << (Argument* pChild) {
        setChild(pChild);
        return this;
    }

    void setChild(Argument* pChild) {
        m_pChild = pChild;
    }

    Argument* getChild() {
        return m_pChild;
    }

    Argument* getChildPtr() {
        return m_pChild;
    }
};

template <class T>
class TArgument : public Argument {
private:
    T*        m_pContainer;
public:
    TArgument(T arg) {
        m_pContainer = new T;
        memcpy(m_pContainer, (const void*)&arg, sizeof(T));
        m_iLenArg = sizeof(T);
        m_strTypeName = std::string(typeid(T).name());
    }
};


class ArgumentList {
private:
    Argument* m_pRoot;
public:
    ArgumentList(Argument root) {
        m_pRoot = &root;
    }

    int count() {
        int i=0;
        Argument* pArg = m_pRoot;
        while(pArg) {
            i++;
            pArg = pArg->getChildPtr();
        }
        return i;
    }
};


void function(ArgumentList arglist) {
    cout << arglist.count() << endl;
}

void main() {
    function(
            ArgumentList( TArgument<int>(32) << TArgument<std::string>("hey") )
        );
}
Avatar billede krismort Nybegynder
23. august 2004 - 23:13 #1
hvad synes man forresten om ideen ?
Avatar billede arne_v Ekspert
23. august 2004 - 23:51 #2
Der er faktisk 2 fejl.

Fejl 1:

Den her er helt forkert:

    //copy construktor
    Argument(const Argument& rhs)
        : m_pChild(0)
    {
    }
Avatar billede arne_v Ekspert
24. august 2004 - 00:05 #3
Faktisk tror jeg at fejl 2 er næsten det samme som fejl 1.

Der sker noget grimy når Argument instanserne bliver destrueret !
Avatar billede bertelbrander Novice
24. august 2004 - 00:08 #4
>krismort, du har ret i at det er en hård banan, så lad mig svare på dit andet spørgsmål:

Jeg synes ikke om ideen. Specielt synes jeg ikke om at tage et kopi af en std::string, som du gør i TArgument construktoren.
Avatar billede bertelbrander Novice
24. august 2004 - 00:26 #5
Følgende ser ud til at køre:

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <windows.h>
#include <stdlib.h>
#include <typeinfo.h>

using namespace std;

class Argument {
private:

public: //protected:
    Argument* m_pChild;
    int          m_iLenArg;
    std::string m_strTypeName;

public:

    Argument(void)
        : m_pChild(0), m_strTypeName("Unknown")
    {
    }

    //copy construktor
    //Argument(const Argument& rhs)
    //{
    //  m_pChild = (Argument *)&rhs;
    //}

    Argument &operator << (Argument &pChild)
    {
        setChild(&pChild);
        return *this;
    }

    void setChild(Argument* pChild) {
        m_pChild = pChild;
    }

    Argument* getChild() {
        return m_pChild;
    }

    Argument* getChildPtr() {
        return m_pChild;
    }
};

template <class T>
class TArgument : public Argument {
private:
    T        m_pContainer;
public:
    TArgument(T arg) {
        m_pContainer = arg;
        m_iLenArg = sizeof(T);
        m_strTypeName = std::string(typeid(T).name());
    }
};


class ArgumentList {
private:
    Argument* m_pRoot;
public:
    ArgumentList(Argument &root) {
        m_pRoot = &root;
    }

    int count() {
        int i=0;
        Argument* pArg = m_pRoot;
        while(pArg) {
            i++;
            cout << pArg->m_strTypeName << endl;
            pArg = pArg->getChildPtr();
        }
        return i;
    }
};


void function(ArgumentList arglist) {
    cout << arglist.count() << endl;
}

void main() {
    TArgument<std::string>SA("hey");
    function(            ArgumentList( TArgument<int>(32) << SA)
        );
}
Avatar billede bertelbrander Novice
24. august 2004 - 00:28 #6
Jeg var nødt til at flytte std::string argumentet ud af kaldet til ArgumentList constructoren, hvilket ødelægger ideen.
Avatar billede bertelbrander Novice
24. august 2004 - 00:48 #7
En lettere forbedret version hvor kaldet er lidt mere som ønsket, men det er stadig ikke kønt:

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <windows.h>
#include <stdlib.h>
#include <typeinfo.h>

using namespace std;

class Argument {
private:

public: //protected:
    Argument* m_pChild;
    int          m_iLenArg;
    std::string m_strTypeName;

public:

    Argument(void)
        : m_pChild(0)
    {
    }

    //copy construktor
    Argument(const Argument& rhs)
    {
      m_pChild = rhs.m_pChild;
      m_iLenArg = rhs.m_iLenArg;
      m_strTypeName = rhs.m_strTypeName;
    }

    Argument &operator << (Argument *pChild)
    {
        setChild(pChild);
        return *this;
    }

    void setChild(Argument* pChild) {
        m_pChild = pChild;
    }

    Argument* getChild() {
        return m_pChild;
    }

    Argument* getChildPtr() {
        return m_pChild;
    }
};

template <class T>
class TArgument : public Argument {
private:
    T        m_pContainer;
    TArgument(TArgument &rhs)
    {
      cout << "Oh-no" << endl;
    }
public:
    TArgument(T arg)
    {
        m_pContainer = arg;
        m_iLenArg = sizeof(T);
        m_strTypeName = std::string(typeid(T).name());
    }
};


class ArgumentList
{
private:
  Argument* m_pRoot;
public:
  ArgumentList(Argument &root)
  {
      m_pRoot = &root;
  }

  int count()
  {
      int i=0;
      Argument* pArg = m_pRoot;
      while(pArg)
      {
          i++;
          cout << pArg->m_strTypeName << endl;
          pArg = pArg->getChildPtr();
      }
      return i;
  }
};

void function(ArgumentList arglist)
{
    cout << arglist.count() << endl;
}

int main()
{
  function(ArgumentList( TArgument<int>(32) << &TArgument<std::string>("hey")));
}
Avatar billede bertelbrander Novice
24. august 2004 - 01:01 #8
Bemærk at TArgument har fået en instans af T og ikke en pointer til en T, hvilket forbedrer metoden en del.

Problemet er så at få hevet data ud fra listen igen.
Avatar billede bertelbrander Novice
24. august 2004 - 23:49 #9
En anden løsning, der dog også har sine svagheder.

Specielt ville jeg gerne bruge referencer i "ArgListClass operator << ...", så man slipper for at kopiere hele listen, men det vil g++ ikke oversætte

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

class ArgClass
{
public:
  enum ArgTypeEnum
  {
      IntType,
      StringType
  };
  ArgClass(int aI) : i(aI), ArgType(IntType)
  {}
  ArgClass(std::string aS) : S(aS), ArgType(StringType)
  {}
  int i;
  std::string S;
  ArgTypeEnum ArgType;
};

std::ostream &operator << (std::ostream &os, const ArgClass &aArg)
{
  if(aArg.ArgType == ArgClass::IntType)
      os << aArg.i;
  else
      os << aArg.S;
  return os;
}

class ArgListClass  : public std::vector<ArgClass>
{
};

ArgListClass operator << (ArgListClass aList, ArgClass aArg)
{
  aList.push_back(aArg);
  return aList;
}

void Func(ArgListClass aArgList)
{
  for(ArgListClass::iterator idx = aArgList.begin(); idx != aArgList.end(); ++idx)
      std::cout << *idx << " ";
}

int main()
{
  Func(ArgListClass() << 1 << 2 << 4 << std::string("Ole"));
}
Avatar billede bertelbrander Novice
26. august 2004 - 20:50 #10
En lidt kønnere version, hvor operatoren bruger referencer.
Den viser samtidig hvordan man kan misbruge mutable keyword'et:

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

class ArgClass
{
public:
  enum ArgTypeEnum
  {
      IntType,
      StringType
  };
  ArgClass(int aI) : i(aI), ArgType(IntType)
  {}
  ArgClass(std::string aS) : S(aS), ArgType(StringType)
  {}
  int i;
  std::string S;
  ArgTypeEnum ArgType;
};

std::ostream &operator << (std::ostream &os, const ArgClass &aArg)
{
  if(aArg.ArgType == ArgClass::IntType)
      os << aArg.i;
  else
      os << aArg.S;
  return os;
}

class ArgListClass
{
public:
  mutable std::vector<ArgClass>List;
};

const ArgListClass &operator << (const ArgListClass &aList, ArgClass aArg)
{
  aList.List.push_back(aArg);
  return aList;
}

void Func(const ArgListClass aArgList)
{
  for(std::vector<ArgClass>::const_iterator idx = aArgList.List.begin(); idx != aArgList.List.end(); ++idx)
      std::cout << *idx << " ";
}

int main()
{
  Func(ArgListClass() << 1 << 2 << 4 << std::string("Ole"));
}
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester