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 876207
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 15, 20262026-05-15T11:23:50+00:00 2026-05-15T11:23:50+00:00

I recently switched back from Java and Ruby to C++, and much to my

  • 0

I recently switched back from Java and Ruby to C++, and much to my surprise I have to recompile files that use the public interface when I change the method signature of a private method, because also the private parts are in the .h file.

I quickly came up with a solution that is, I guess, typical for a Java programmer: interfaces (= pure virtual base classes). For example:

BananaTree.h:

class Banana;

class BananaTree
{
public:
  virtual Banana* getBanana(std::string const& name) = 0;

  static BananaTree* create(std::string const& name);
};

BananaTree.cpp:

class BananaTreeImpl : public BananaTree
{
private:
  string name;

  Banana* findBanana(string const& name)
  {
    return //obtain banana, somehow;
  }

public:
  BananaTreeImpl(string name) 
    : name(name)
  {}

  virtual Banana* getBanana(string const& name)
  {
    return findBanana(name);
  }
};

BananaTree* BananaTree::create(string const& name)
{
  return new BananaTreeImpl(name);
}

The only hassle here, is that I can’t use new, and must instead call BananaTree::create(). I do not think that that is really an problem, especially since I expect to be using factories a lot anyway.

Now, the wise men of C++ fame, however, came up with another solution, the pImpl idiom. With that, if I understand it correctly, my code would look like:

BananaTree.h:

class BananaTree
{
public:
  Banana* addStep(std::string const& name);

private:
  struct Impl;
  shared_ptr<Impl> pimpl_;
};

BananaTree.cpp:

struct BananaTree::Impl
{
  string name;

  Banana* findBanana(string const& name)
  {
    return //obtain banana, somehow;
  }

  Banana* getBanana(string const& name)
  {
    return findBanana(name);
  }

  Impl(string const& name) : name(name) {}
}

BananaTree::BananaTree(string const& name)
  : pimpl_(shared_ptr<Impl>(new Impl(name)))
{}

Banana* BananaTree::getBanana(string const& name)
{
  return pimpl_->getBanana(name);
}

This would mean I have to implement a decorator-style forwarding method for every public method of BananaTree, in this case getBanana. This sounds like an added level of complexity and maintenance effort that I prefer not to require.

So, now for the question: What is wrong with the pure virtual class approach? Why is the pImpl approach so much better documented? Did I miss anything?

  • 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-15T11:23:51+00:00Added an answer on May 15, 2026 at 11:23 am

    I can think of a few differences:

    With the virtual base class you break some of the semantics people expect from well-behaved C++ classes:

    I would expect (or require, even) the class to be instantiated on the stack, like this:

    BananaTree myTree("somename");
    

    otherwise, I lose RAII, and I have to manually start tracking allocations, which leads to a lot of headaches and memory leaks.

    I also expect that to copy the class, I can simply do this

    BananaTree tree2 = mytree;
    

    unless of course, copying is disallowed by marking the copy constructor private, in which case that line won’t even compile.

    In the above cases, we obviously have the problem that your interface class doesn’t really have meaningful constructors. But if I tried to use code such as the above examples, I’d also run afoul of a lot of slicing issues.
    With polymorphic objects, you’re generally required to hold pointers or references to the objects, to prevent slicing. As in my first point, this is generally not desirable, and makes memory management much harder.

    Will a reader of your code understand that a BananaTree basically doesn’t work, that he has to use BananaTree* or BananaTree& instead?

    Basically, your interface just doesn’t play that well with modern C++, where we prefer to

    • avoid pointers as much as possible, and
    • stack-allocate all objects to benefit form automatic lifetime management.

    By the way, your virtual base class forgot the virtual destructor. That’s a clear bug.

    Finally, a simpler variant of pimpl that I sometimes use to cut down on the amount of boilerplate code is to give the “outer” object access to the data members of the inner object, so you avoid duplicating the interface. Either a function on the outer object just accesses the data it needs from the inner object directly, or it calls a helper function on the inner object, which has no equivalent on the outer object.

    In your example, you could remove the function and Impl::getBanana, and instead implement BananaTree::getBanana like this:

    Banana* BananaTree::getBanana(string const& name)
    {
      return pimpl_->findBanana(name);
    }
    

    then you only have to implement one getBanana function (in the BananaTree class), and one findBanana function (in the Impl class).

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

Sidebar

Ask A Question

Stats

  • Questions 441k
  • Answers 441k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer The best approach is to use event-handlers as a publisher-subscriber… May 15, 2026 at 5:38 pm
  • Editorial Team
    Editorial Team added an answer The home screen doesn't scroll between activities it only scrolls… May 15, 2026 at 5:38 pm
  • Editorial Team
    Editorial Team added an answer You can always use TransactionScope together with the appropriate locking… May 15, 2026 at 5:38 pm

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

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.