-4

I have an abstract class for Serializing data as follows

template<class T>
class Serialize{
    public:
       virtual string serialize() = 0;
       virtual T deSerialize(string value) = 0;
 }

I also have a data model a follows

 class PersonModel: public Serialize<PersonModel> {
       ...
       public:
           ...
           string serialize() { return "The serialized form";}
           T deSerialize(string value) {return PersonModel();}
  }

Now I have a generic context class as follows:

 template<class T>
 class DC{
     private:
        vector<T> data;
     public:
        vector<string> read(){
            for each(auto i in data){
                Serialize<T> *getSerializedData = dynamic_cast<Serialize<T>*>(i);
            }
        }

C++ showing the following error for the above cast:

Error C2682 cannot use 'dynamic_cast' to convert from 'PersonModel' to 'Serialize<PersonModel> *'

How to work this around?

Arnold Zahrneinder
  • 4,788
  • 10
  • 40
  • 76

1 Answers1

1

Assuming you declared the instance of DC<T> as DC<PersonModel> the error is obvious: You can't convert a non-pointer object to a pointer to that object (or a pointer to the base class).

Loop over references instead, and you don't actually need to do any casting:

for (auto& i : data){
    // i is a reference which makes polymorphism work
    // i also "is-a" Serialize<PersonModel> object reference due to the inheritance
    i.serialize();  // Will work just fine, no casting needed
}
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • It shows the exact same error, I already tried it before posting the question. – Arnold Zahrneinder Feb 21 '16 at 13:58
  • 1
    @Arrrr It can't, not unless you do the illegal casting to a pointer from a non-pointer object. *Don't* do the casting, it's not needed. – Some programmer dude Feb 21 '16 at 13:59
  • The Casting is needed since this is C++, if it was C# it would not be needed. C++ does not have Generic Constraints on high level. – Arnold Zahrneinder Feb 21 '16 at 14:00
  • 1
    @Arrrr Then the question is missing some crucial information, *why* do you need to cast? What are you actually trying to do in the loop? – Some programmer dude Feb 21 '16 at 14:01
  • Your updated answer also does not work, the complier at that point is unaware of the existence of the `Serialize` method. That's why. – Arnold Zahrneinder Feb 21 '16 at 14:02
  • 1
    @Arrrr Then you definitely are doing something you don't show us. The `PersonModel` ***is a*** `Serialize`, and it even have the `serialize` function overridden so if the compiler says it doesn't find that function you're doing something you're not showing us. Also, `Serialize` or `serialize`? There's a big difference there, as C++ as case-sensitive. – Some programmer dude Feb 21 '16 at 14:04
  • There is no reason for me to hide something, that is exactly the code unless you wanna see a load of setter and getter which is not related to that part. – Arnold Zahrneinder Feb 21 '16 at 14:06
  • @Arrrr The problem you are asking about is solved by my answer. If that leads to another problem you should ask another question about that, and then include the code that calls `serialize` (or `Serialize`, whichever it is that is correct) together with that error.. – Some programmer dude Feb 21 '16 at 14:09
  • No it does not solve it, how can C++ know about the methods of T in compile time?? The type is fully unknown and C++ doesn't have generic constraint like the `where` clause in C#. Assuming I gotta use a pointer, the serialize method must be called as "->Serialize()" not using a dot. – Arnold Zahrneinder Feb 21 '16 at 14:12
  • @Arrrr Because the compiler knows what `T` is *at the time of compilation* otherwise how you could declare an object of class `DC`? It's right there in the declaration, the `T` is replaced by `PersonModel` everywhere you use `T` by the compiler. In an instance of `DC` the `T` *means* `PersonModel`. If you get compiler errors saying that a member function is not found, then you either have spelled the function name wrong (like writing wrong case `S` instead of `s`) or there's something else going on. – Some programmer dude Feb 21 '16 at 14:20
  • T is unknown at its own context!!!! but known at the point where it is used!!!! There is no way for the T to be a known type unless you use constraints which is not available in C++!!!! I have no idea based on what you even say that. – Arnold Zahrneinder Feb 21 '16 at 14:24
  • @Arrrr After some simplifying to remove unneeded code for this example (and error fixing!) [I tested it and it seems to work well](http://ideone.com/aP3BCG). What you seem to fail to understand that there exists no `DC` instance, there is no `DC::read` function in any program you make using your class. What *does* exist is an instance of the `DC` class, and a `DC::read` function. `T` is definitely known at the time of the compilation, or you would get compiler error. I think you need to read up a little on how templates actually work in C++. – Some programmer dude Feb 21 '16 at 15:22