Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Generic Get and Set as interface

Generic Get and Set as interface

Scheduled Pinned Locked Moved C / C++ / MFC
comtutorial
9 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    Durga_Devi
    wrote on last edited by
    #1

    Hi all, I want to have an interface for setting and getting the different value from/to com dll. The value can be of any datatype, i,e it support int, char, long, short, string. Can any one suggest how to handle this. I know we cant have virtual template function or interface as a template. Any idea is highly appreciated. Thanks in advance. regards, Durga

    CPalliniC P 2 Replies Last reply
    0
    • D Durga_Devi

      Hi all, I want to have an interface for setting and getting the different value from/to com dll. The value can be of any datatype, i,e it support int, char, long, short, string. Can any one suggest how to handle this. I know we cant have virtual template function or interface as a template. Any idea is highly appreciated. Thanks in advance. regards, Durga

      CPalliniC Offline
      CPalliniC Offline
      CPallini
      wrote on last edited by
      #2

      You may use a VARIANT[^] data type or a similar mechanism.

      Veni, vidi, vici.

      In testa che avete, signor di Ceprano?

      1 Reply Last reply
      0
      • D Durga_Devi

        Hi all, I want to have an interface for setting and getting the different value from/to com dll. The value can be of any datatype, i,e it support int, char, long, short, string. Can any one suggest how to handle this. I know we cant have virtual template function or interface as a template. Any idea is highly appreciated. Thanks in advance. regards, Durga

        P Offline
        P Offline
        pasztorpisti
        wrote on last edited by
        #3

        One generic solution that might be suitable has already been posted by CPallini. Another one more C++ish solution could be something like this: Define a base class for your different types:

        class CValue
        {
        };

        Derive a class for all types you support:

        class CStringValue : public CValue
        {
        public:
        // CStringValue specific methods like void SetValue(const std::string&) and
        // const std::string& GetValue();
        private:
        std::string m_Value;
        };

        class CIntValue : public CValue
        {
        public:
        // CIntValue specific methods like void SetValue(int) and
        // int GetValue();
        private:
        int m_Value;
        };

        The advantage of this solution that your data type can be anything, it can contain an int array, or one of your own classes if you want and not just 'primitives'. The derived class itself can be a type put together by compositing other types... Your interface methods should look like the following:

        void SetValue(CValue* val);
        CValue* GetValue();

        We reached the point where we want to use the actual value but inside SetValue() all we have is a CValue* that is useless in its current form so we put in some useful virtual methods in this base class. First I want to be able to decide the exact type of the value. For this reason I usually use one or both of the following methods: 1. introducing an enum that contains a member for each supported possible datatype and you can query it from the base class. 2. virtual downcast methods in the base class.

        class CStringValue;
        class CIntValue;

        class CValue
        {
        public:
        enum EType
        {
        EType_String,
        EType_Int,
        };
        virtual Etype GetType() = 0;

        // Downcast methods, not the most beautiful OO solution of the world but sometimes
        // in a fixed size class hierarchy like this it is acceptable and comfortable, and
        // more beautiful than using for example C++'s dynamic\_cast. If quite comfortable
        // to say for example "if (CStringValue\* sv = val->AsStringValue())"
        
        // override this only in CStringValue and put "return this;" into the method body.
        virtual CStringValue\* AsStringValue() { return NULL; }
        // override this only in CIntValue and put "return this;" into the method body.
        virtual CIntValue\* AsIntValue() { return NULL; }
        

        };

        Note that both the type enum and downcast methods are against the dynamic extensibility of the class hierarchy from outside world, ot

        D 1 Reply Last reply
        0
        • P pasztorpisti

          One generic solution that might be suitable has already been posted by CPallini. Another one more C++ish solution could be something like this: Define a base class for your different types:

          class CValue
          {
          };

          Derive a class for all types you support:

          class CStringValue : public CValue
          {
          public:
          // CStringValue specific methods like void SetValue(const std::string&) and
          // const std::string& GetValue();
          private:
          std::string m_Value;
          };

          class CIntValue : public CValue
          {
          public:
          // CIntValue specific methods like void SetValue(int) and
          // int GetValue();
          private:
          int m_Value;
          };

          The advantage of this solution that your data type can be anything, it can contain an int array, or one of your own classes if you want and not just 'primitives'. The derived class itself can be a type put together by compositing other types... Your interface methods should look like the following:

          void SetValue(CValue* val);
          CValue* GetValue();

          We reached the point where we want to use the actual value but inside SetValue() all we have is a CValue* that is useless in its current form so we put in some useful virtual methods in this base class. First I want to be able to decide the exact type of the value. For this reason I usually use one or both of the following methods: 1. introducing an enum that contains a member for each supported possible datatype and you can query it from the base class. 2. virtual downcast methods in the base class.

          class CStringValue;
          class CIntValue;

          class CValue
          {
          public:
          enum EType
          {
          EType_String,
          EType_Int,
          };
          virtual Etype GetType() = 0;

          // Downcast methods, not the most beautiful OO solution of the world but sometimes
          // in a fixed size class hierarchy like this it is acceptable and comfortable, and
          // more beautiful than using for example C++'s dynamic\_cast. If quite comfortable
          // to say for example "if (CStringValue\* sv = val->AsStringValue())"
          
          // override this only in CStringValue and put "return this;" into the method body.
          virtual CStringValue\* AsStringValue() { return NULL; }
          // override this only in CIntValue and put "return this;" into the method body.
          virtual CIntValue\* AsIntValue() { return NULL; }
          

          };

          Note that both the type enum and downcast methods are against the dynamic extensibility of the class hierarchy from outside world, ot

          D Offline
          D Offline
          Durga_Devi
          wrote on last edited by
          #4

          Thanks pal. Thanks for ur input. I will try using the first method.

          P 1 Reply Last reply
          0
          • D Durga_Devi

            Thanks pal. Thanks for ur input. I will try using the first method.

            P Offline
            P Offline
            pasztorpisti
            wrote on last edited by
            #5

            You are welcome! Depending on the complexity and the requirements of your project my solution can be a heavy over-engineering to solve a very small problem. You have to draw the line yourself! Good luck!

            D 1 Reply Last reply
            0
            • P pasztorpisti

              You are welcome! Depending on the complexity and the requirements of your project my solution can be a heavy over-engineering to solve a very small problem. You have to draw the line yourself! Good luck!

              D Offline
              D Offline
              Durga_Devi
              wrote on last edited by
              #6

              Hi pasztorpisti, I have one doubt. I can go with the enumerator alone , instead of having the downcast method? Can you please explain me how it has to be in implementation class. Thanks in advance.

              P 1 Reply Last reply
              0
              • D Durga_Devi

                Hi pasztorpisti, I have one doubt. I can go with the enumerator alone , instead of having the downcast method? Can you please explain me how it has to be in implementation class. Thanks in advance.

                P Offline
                P Offline
                pasztorpisti
                wrote on last edited by
                #7

                I don't exactly know the problem you wanna solve and don't know what part is unclear for you. If an enum + GetType() is enough for you then you can omit the downcast methods but either way you choose you will have to downcast the object somehow so without downcast methods you will have to use C++ static cast. As I described in some situations you might need neither the enum nor the downcast, for example if a virtual method like ToString() can do the job.

                D 1 Reply Last reply
                0
                • P pasztorpisti

                  I don't exactly know the problem you wanna solve and don't know what part is unclear for you. If an enum + GetType() is enough for you then you can omit the downcast methods but either way you choose you will have to downcast the object somehow so without downcast methods you will have to use C++ static cast. As I described in some situations you might need neither the enum nor the downcast, for example if a virtual method like ToString() can do the job.

                  D Offline
                  D Offline
                  Durga_Devi
                  wrote on last edited by
                  #8

                  HI pasztporpist As per your input i have done the code

                  // App_Datatype.cpp : Defines the entry point for the console application.
                  //
                  #include <iostream>
                  #include <tchar.h>
                  #include <stdio.h>

                  class CStringValue;
                  class CValue
                  {
                  public:

                  enum EType
                  {
                      EType\_String,
                      EType\_Int,
                  };
                  
                  
                  virtual EType getDataType() = 0;
                  
                  virtual CStringValue\* AsStringValue() { return NULL; }
                  

                  };

                  class CStringValue : public CValue
                  {
                  private:
                  std::string m_strValue;

                  public:

                  void set(const std::string &strVal)
                  {
                  	m\_strValue = strVal;
                  }
                  
                  std::string get()
                  {
                  	return m\_strValue;
                  }
                  
                  CStringValue\* AsStringValue()
                  {
                  	return this;
                  }
                  
                  EType getDataType()
                  {
                  	return CValue::EType\_String;
                  }
                  

                  };

                  void print(CValue *pVal)
                  {
                  if(pVal->getDataType() == CValue::EType_String)
                  {
                  CStringValue *val = pVal->AsStringValue();
                  std::cout<<val->get().c_str();
                  }
                  }

                  int _tmain(int argc, _TCHAR* argv[])
                  {

                  CStringValue \*val = new CStringValue();
                  val->set("Hai");
                  
                  print(val);
                  
                  return 0;
                  

                  }

                  Is it correct? If not tell me where i did a mistake

                  P 1 Reply Last reply
                  0
                  • D Durga_Devi

                    HI pasztporpist As per your input i have done the code

                    // App_Datatype.cpp : Defines the entry point for the console application.
                    //
                    #include <iostream>
                    #include <tchar.h>
                    #include <stdio.h>

                    class CStringValue;
                    class CValue
                    {
                    public:

                    enum EType
                    {
                        EType\_String,
                        EType\_Int,
                    };
                    
                    
                    virtual EType getDataType() = 0;
                    
                    virtual CStringValue\* AsStringValue() { return NULL; }
                    

                    };

                    class CStringValue : public CValue
                    {
                    private:
                    std::string m_strValue;

                    public:

                    void set(const std::string &strVal)
                    {
                    	m\_strValue = strVal;
                    }
                    
                    std::string get()
                    {
                    	return m\_strValue;
                    }
                    
                    CStringValue\* AsStringValue()
                    {
                    	return this;
                    }
                    
                    EType getDataType()
                    {
                    	return CValue::EType\_String;
                    }
                    

                    };

                    void print(CValue *pVal)
                    {
                    if(pVal->getDataType() == CValue::EType_String)
                    {
                    CStringValue *val = pVal->AsStringValue();
                    std::cout<<val->get().c_str();
                    }
                    }

                    int _tmain(int argc, _TCHAR* argv[])
                    {

                    CStringValue \*val = new CStringValue();
                    val->set("Hai");
                    
                    print(val);
                    
                    return 0;
                    

                    }

                    Is it correct? If not tell me where i did a mistake

                    P Offline
                    P Offline
                    pasztorpisti
                    wrote on last edited by
                    #9

                    Instead of

                    std::string get()
                    {
                        return m\_strValue;
                    }
                    

                    I would write this:

                    <pre lang="c++">
                    const std::string& get() const
                    {
                    return m_strValue;
                    }
                    </pre>

                    getDataType() can also be a const method. In you example (with the print function) I would rather use the virtual ToString() method instead of a type enum or casting.

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups