CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Jun 2012
    Posts
    38

    Share-pointer and void

    I have a share-pointer defined as
    typedef std::share_ptr<MyClass> MyClassPtr;

    and a class
    Code:
    class Example
    {
    public:
       MyClassPtr DoSomething()
      {
         return new MyClass();
       }
            
    };
    Now that I would like to implement a polymophic behavior as
    Code:
    class BabyExample:public Example
    {
    public:
        MyClassPtr DoSomething()
        {
            return new MyClass_Baby();
        }
    };
    This is what I have shortened up, the project code is a lot and messy. For this simplified (not simple) case, it sure works but in my application, DoSomething in the child class is never called, but the base class' instead. However, if I could change MyClassPtr into void*, it would work for sure!
    I have tested this in those behaviors without share_ptr.

    My questions are,
    1. what actually happened that prevents the debugger from reaching the child method.
    2. how can I change share-ptr to void*/void/void& ?

    Thank you,

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Share-pointer and void

    Quote Originally Posted by terminalXXX View Post
    This is what I have shortened up, the project code is a lot and messy.
    Take the time to post a full, but smallest example that demonstrates the error.

    Every C++ syntax and runtime error with respect to polymorphism can be duplicated with just a few lines of real code, some classes with one or two empty virtual function calls, etc. It doesn't take a whole project to duplicate an error.

    So I doubt that what you're describing is what is really happening. If it were the case that the base class function is always called either:

    1) You are explicitly calling the base class version in some way.
    2) The base class version is not the same signature as the derived class version.
    3) The base class version is called due to an issue with single dispatch and C++ (in that case, the visitor pattern and double dispatch pattern would be suitable).

    So to answer any of your questions, again, post a full but smallest example that when we compile it without changing any lines of code to get it to compile, we get the exact same error at runtime that you're seeing.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; June 28th, 2013 at 10:51 AM.

  3. #3
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Share-pointer and void

    For this simplified (not simple) case, it sure works but in my application, DoSomething in the child class is never called, but the base class' instead
    Again, every error such as what you described can be duplicated with a simple case. The C++ language doesn't behave differently just because the code base is larger.

    It isn't an issue with memory corruption, so the error can be duplicated with a simple case. But we can only comment if you post such a simple case, which you haven't done.

    Regards,

    Paul McKenzie

  4. #4
    2kaud's Avatar
    2kaud is online now Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Share-pointer and void

    Quote Originally Posted by terminalXXX View Post
    This is what I have shortened up, the project code is a lot and messy. For this simplified (not simple) case, it sure works but in my application, DoSomething in the child class is never called, but the base class' instead. However, if I could change MyClassPtr into void*, it would work for sure!
    If the project code is 'messy' as you state, then it is inviting errors. A good first step would be to refactor the code to make it 'clean' and easy to understand and maintain. As you say, for the simplifed case you have posted it works but not in the application. So something is 'different' in the application. Unless the code is clean and easy to understand, finding this issue will be more difficult. Just changing MyClassPtr to void* is probably not the answer as this is hiding the real problem.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  5. #5
    Join Date
    May 2007
    Posts
    811

    Re: Share-pointer and void

    Code:
    class Example
    {
    public:
       virtual MyClassPtr DoSomething()
      {
         return new MyClass();
       }
            
    };

  6. #6
    2kaud's Avatar
    2kaud is online now Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Share-pointer and void

    DoSomething in the child class is never called, but the base class' instead.
    How are you accessing the class functions? As Paul said in post #2, it would be helpful if you could post a full working program that demonstrates the error.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  7. #7
    Join Date
    Jun 2012
    Posts
    38

    Re: Share-pointer and void

    Quote Originally Posted by 2kaud View Post
    How are you accessing the class functions? As Paul said in post #2, it would be helpful if you could post a full working program that demonstrates the error.
    I have posted it in some of my previous posts, I don't know what else I can extract from the real code to demonstrate the problem. I change all user-defined time to void* (return types and parameters of functions), all of them work fine then. Functions with POD parameters or POD return types, I didn't change them, it works too. But if I keep the same signature the the base class methods with non-POD types, only the bases methods are called

    Again here

    Code:
    class SecondBase:FirstBase
    {
       public: 
         UserType func(AnotherType type)
         {
              return FirstBase::StaticMethodOfUserType();
         }
    };
    
    class ThirdBase:SecondBase
    {
        virtual UserType DoFunc(AnotherType type)
        {
            return func(type);
        }
        void CallDoFunc(){DoFunc(type);}
    };
    
    class FourthBase:ThirdBase
    {
        virtual UserType DoFunc(AnotherType type)
        {
            return new MyNewType();
        }
        //CallDoFunc of the ThirdBase
    };
    I have spent the last 7 days to understand why the Dofunc in FourthBase never gets called but failed to see the reason.
    In my project if I change UserType and AnotherType into void*, it will do the job for me. Why is it ?

  8. #8
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Share-pointer and void

    Quote Originally Posted by terminalXXX View Post
    I have posted it in some of my previous posts, I don't know what else I can extract from the real code to demonstrate the problem.
    I don't care about your real code.

    What I want you to do is start from scratch and create a program that does what you say it does. If you cannot do this, then there is something flawed in your description, and what you're describing is not what is in your program. So instead of trying to extract something from your program, give us a real program that shows this behaviour.

    Start with this:
    Code:
    #include <memory>
    #include <iostream>
    
    typedef std::shared_ptr<int> IntPtr;
    
    class Base
    {
    public:
        virtual ~Base() {}
        virtual IntPtr func1() { return IntPtr(new int(1)); }
    };
    
    class Derived : public Base
    {
    public:
        IntPtr func1() { return IntPtr(new int(2)); }
    };
    
    class Derived2 : public Derived
    {
    public:
        IntPtr func1() { return IntPtr(new int(3)); }
    };
    
    
    using namespace std;
    
    int main()
    {
        {
            Base *b = new Derived;
            IntPtr x = b->func1();
            cout << *x << "\n";
            delete b;
        }
    
        {
           Base *b = new Derived2;
           IntPtr x = b->func1();
           cout << *x << "\n";
           delete b;
        }
    }
    
    Output:
    2
    3
    Note how the example above is a full example. So take that example above and change it to one that works differently. Then convince us that you can make it print "1" by calling func1() from any of the derived classes, given that you have a base class pointer to the derived object. Then convince us that given those changes, that "void*" fixes the problem.

    This is how you duplicate a runtime scenario with C++. Again, C++ rules do not change just because the code is large, small, or in-between.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; June 28th, 2013 at 03:18 PM.

  9. #9
    2kaud's Avatar
    2kaud is online now Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Share-pointer and void

    You are showing the skeleton classes, but not how they are used/called. You need to post a program that uses these classes that demonstrates the problem.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  10. #10
    Join Date
    Jun 2012
    Posts
    38

    Re: Share-pointer and void

    Thanks Paul and 2kaud,

    We work only on mixed mode dlls and CLI test classes, the test class method is simple and does exactly the same job as the main function does in Paul's example. And sure, if I make a small program similar to Paul's, the program is always compiled fine and offers the executed results as expected while the original source code in my project never exhibits polymorphic behaviors without use of void* in places of user-defined types except share pointers (I would like to mock the share pointers too but it didn't work out for me).

  11. #11
    2kaud's Avatar
    2kaud is online now Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Share-pointer and void

    Then, IMO, consideration should be given to refactoring the code (as mentioned in post #4) to make it 'clean' and easy to follow and maintain. Having void* in place of user-defined types to achieve a particular behaviour is symptomatic of underlying problems with the design/structure/code.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured