Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6743961
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T12:01:36+00:00 2026-05-26T12:01:36+00:00

My program needs to handle different kinds of notes: NoteShort , NoteLong … Different

  • 0

My program needs to handle different kinds of “notes”: NoteShort, NoteLong… Different kinds of notes should be displayed in the GUI in different ways. I defined a base class of these notes, called NoteBase.

I store these notes in XML; and I have a class which reads from the XML file and store notes’ data in vector<NoteBase *> list. Then I found I cannot get their own types, because they are already converted to NoteBase *!

Though if(dynamic_cast<NoteLong *>(ptr) != NULL) {...} may works, it’s really too ugly. Implementing functions take NoteShort * or NoteLong * as parameter don’t work. So, any good way to deal with this problem?

UPDATE: Thank you guys for replying. I don’t think it should happen neither — but it did happened. I implemented it in another way, and it’s now working. However, as far as I remember, I indeed declared the (pure) virtual function in NoteBase, but forgot to declare it again in headers of the deriving classes. I guess that’s what caused the issue.

UPDATE 2 (IMPORTANT):
I found this quotation from C++ Primer, which may be helpful to others:

What is sometimes a bit more surprising is that the restriction on
converting from base to derived exists even when a base pointer or
reference is actually bound to a derived object:

 Bulk_item bulk;
 Item_base *itemP = &bulk;  // ok: dynamic type is Bulk_item
 Bulk_item *bulkP = itemP;  // error: can't convert base to derived

The compiler has no way to know at compile time that a specific
conversion will actually be safe at run time. The compiler looks only
at the static types of the pointer or reference to determine whether a
conversion is legal. In those cases when we know that the conversion
from base to derived is safe, we can use a static_cast (Section
5.12.4, p. 183) to override the compiler. Alternatively, we could request a conversion that is checked at run time by using a
dynamic_cast, which is covered in Section 18.2.1 (p. 773).

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T12:01:37+00:00Added an answer on May 26, 2026 at 12:01 pm

    There are two significant trains of thought and code here, so shortest first:


    You may not need to cast back up. If all Notes provide a uniform action (say Chime), then you can simply have:

    class INote
    {
        virtual void Chime() = 0;
    };
    
    ...
    for_each(INote * note in m_Notes)
    {
        note->Chime();
    }
    

    and each Note will Chime as it should, using internal information (duration and pitch, for example).

    This is clean, simple, and requires minimal code. It does mean the types all have to provide and inherit from a particular known interface/class, however.


    Now the longer and far more involved methods occur when you do need to know the type and cast back up to it. There are two major methods, and a variant (#2) which may be used or combined with #3:

    1. This can be done in the compiler with RTTI (runtime type information), allowing it to safely dynamic_cast with good knowledge of what is allowed. This only works within a single compiler and perhaps single module (DLL/SO/etc), however. If your compiler supports it and there are no significant downsides of RTTI, it is by far the easiest and takes the least work on your end. It does not, however, allow the type to identify itself (although a typeof function may be available).

      This is done as you have:

      NewType * obj = dynamic_cast<NewType*>(obj_oldType);
      
    2. To make it entirely independent, adding a virtual method to the base class/interface (for example, Uuid GetType() const;) allows the object to identify itself at any time. This has a benefit over the third (true-to-COM) method, and a disadvantage: it allows the user of the object to make intelligent and perhaps faster decisions on what to do, but requires a) they cast (which may necessitate and unsafe reinterpret_cast or C-style cast) and b) the type cannot do any internal conversion or checking.

      ClassID id = obj->GetType();
      if (id == ID_Note_Long)
          NoteLong * note = (NoteLong*)obj;
          ...
      
    3. The option which COM uses is to provide a method of the form RESULT /* success */ CastTo(const Uuid & type, void ** ppDestination);. This allows the type to a) check the safety of the cast internally, b) perform the cast internally at its own discretion (there are rules on what can be done) and c) provide an error if the cast is impossible or fails. However, it a) prevents the user form optimizing well and b) may require multiple calls to find a succesful type.

      NoteLong * note = nullptr;
      if (obj->GetAs(ID_Note_Long, &note))
          ...
      

    Combining the latter two methods in some fashion (if a 00-00-00-0000 Uuid and nullptr destination are passed, fill the Uuid with the type’s own Uuid, for example) may be the most optimal method of both identifying and safely converting types. Both the latter methods, and them combined, are compiler and API independent, and may even achieve language-independence with care (as COM does, in qualified manner).

    ClassID id = ClassID::Null;
    obj->GetAs(id, nullptr);
    if (id == ID_Note_Long)
        NoteLong * note;
        obj->GetAs(ID_Note_Long, &note);
        ...
    

    The latter two are particularly useful when the type is almost entirely unknown: the source library, compiler, and even language are not known ahead of time, the only available information is that a given interface is provided. Working with such little data and unable to use highly compiler-specific features such as RTTI, requiring the object to provide basic information about itself is necessary. The user can then ask the object to cast itself as needed, and the object is has full discretion as to how that’s handled. This is typically used with heavily virtual classes or even interfaces (pure virtual), as that may be all the knowledge the user code may have.

    This method is probably not useful for you, in your scope, but may be of interest and is certainly important as to how types can identify themselves and be cast back "up" from a base class or interface.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

The program needs to take in a simple string from the user and display
My program needs to know when a user ejects cd disc. Is there some
My program needs to do 2 things. Extract stuff from a webpage. Do stuff
My program needs to make use of void* in order to transport data or
My program needs to listen incoming socket connections (lets agree on port 8765), but
My C++ program needs a block of uninitialized memory and a void* pointer to
I have a bunch of PDF files and my Perl program needs to do
I am working on a small application in VB.NET. The program needs administrator privilege
Alright, quick question. A server is running in Eastern Time. PHP program needs to
I have a program which needs to behave slightly differently on Tiger than on

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.