views:

76

answers:

1

hello, I have this snippet of the code:

void addLineRelative(LineNumber number, LineNumber relativeNumber) {
            list<shared_ptr<Line> >::iterator i;
            findLine(i, number);
            if(i == listOfLines.end()){
                throw "LineDoesNotExist";
            }

   line 15  if(dynamic_cast<shared_ptr<FamilyLine> >(*i)){
                cout << "Family Line";
            } else {
                throw "Not A Family Line";
            }
        }

I have class Line and derived from it FamilyLine and RegularLine, so I want find FamilyLine

my program fails on the line 15, I receive an error

cannot dynamic_cast target is not pointer or reference

can somebody please help, thanks in advance

edited

I tried this one:

shared_ptr<FamilyLine> ptr(dynamic_cast<shared_ptr<FamilyLine> >(*i));
if(ptr){
    //do stuff
}

the same error

edited

void addLineRelative(LineNumber number, LineNumber relativeNumber) {
        list<shared_ptr<Line> >::iterator i;
        findLine(i, number);
        if(i == listOfLines.end()){
            throw "LineDoesNotExist";
        }

        shared_ptr<FamilyLine> ptr(dynamic_pointer_cast<FamilyLine>(*i));
        if (ptr){
            cout << "Family Line";
        } else {
            throw "Not A Family Line";
        }
    }

receive this error

Multiple markers at this line
    - `dynamic_pointer_cast' was not declared in this 
     scope
    - unused variable 'dynamic_pointer_cast'
    - expected primary-expression before '>' token
+1  A: 

shared_ptr does not implicitly convert to a pointer - it is a class-type object - and dynamic_cast, static_cast and const_cast all operate on pointers only.

While you could use dynamic_cast on shared_ptr<T>::get(), its better to use dynamic_pointer_cast<FamilyLine>() instead as you might otherwise accidentally introduce double-deletes:

Returns:
* When dynamic_cast<T*>(r.get()) returns a nonzero value, a shared_ptr<T> object that stores a copy of it and shares ownership with r;
* Otherwise, an empty shared_ptr<T> object.
[...]
Notes: the seemingly equivalent expression

shared_ptr<T>(dynamic_cast<T*>(r.get()))

will eventually result in undefined behavior, attempting to delete the same object twice.

E.g.:

shared_ptr<FamilyLine> ptr(dynamic_pointer_cast<FamilyLine>(*i));
if (ptr) {
    // ... do stuff with ptr
} 
Georg Fritzsche
@Georg Fritzsche: dynamic_pointer_cast, where can I find it, my compiler doesn't know about it
helloWorld
@hello: What version are you using, TR1 et al (use `<memory>`) or boost (`<boost/pointer_cast.hpp>`)? *(Side-note: The owner of a post is always notified of comments, so the @user syntax isn't neccessary in this case)*
Georg Fritzsche
@Georg Fritzsche: I don't know, I'm working on Eclipse Galileo and I use using namespace std;
helloWorld
Then you are probably using TR1 or C++0x features and `#include <memory>` should be sufficient.
Georg Fritzsche
How can I check with which libraries do I work?
helloWorld
Well, every C++ library worth its grain either has its types and functions in a namespace (like `std` for the standard library, `boost` for Boost, ...) or at least gives them a common prefix (`Q` for Qt). So as long as you don't have any using directives for `boost` anywhere but have them for `std`, the `shared_ptr` has to come from the standard library or an extension of it. This confusion is by the way a good argument against putting `using namespace foo;` everywhere.
Georg Fritzsche
I tried it, but it gives me an error about unused variable dynamic_pointer_cast, which namespace do I need?
helloWorld
Probably `std` - can you add what you tried to the question?
Georg Fritzsche
@hello: Do you have `#include <memory>`? Do you use any special includes (i.e. besides `<memory>`) for `shared_ptr`?
Georg Fritzsche
yes, I did #include <memory>, yes I use #include "shared_ptr.h"
helloWorld
Aha, what is `shared_ptr.h`? Where does that come from?
Georg Fritzsche
there I have all difinitions and implementations of the shared_ptr, but it is working perfectly, I checked it
helloWorld
@hello: What is that, is that a custom implementation of `shared_ptr`? Or did you extract it from Boost? If its custom, its rather confusing - if you use `shared_ptr` in C++ people expect it to be either from TR1, the next C++ standard or Boost.
Georg Fritzsche
yes it is a custom implementation of shared_ptr, I received it from lecturer, so it might work, can we return please a little bit: can I do something like this:shared_ptr<FamilyLine> ptr(dynamic_cast<FamilyLine*>((*i).get()));
helloWorld
oh, yeah, thanks a lot, your answer is great, You are the best:)
helloWorld
it works, finally
helloWorld
@hello: It might seem to work, but it has the problem that `ptr(x)` takes ownership of the instance `x` points to and thinks it has to `delete` the pointer it got which would lead to a double `delete` - so either your `shared_ptr` has a constructor that does not take ownership or you have to ask the lecturer how you are supposed to do this.
Georg Fritzsche
If it is similar to Boosts version and it has a version that allows `shared_ptr<FamilyLine> p(*i, dynamic_cast<FamilyLine*>(i->get()));` then `p` should share ownership with `*i`.
Georg Fritzsche