cm007
cm007

Reputation: 1392

C++ equivalent of C# nested private classes

I am learning C++ coming from C#. In C#, there can be classes such as the following:

public abstract class BankAccount
{
  private BankAccount() {} // prevent third-party subclassing.
  private sealed class SavingsAccount : BankAccount { ... }
  private sealed class ChequingAccount : BankAccount { ... }
  public static BankAccount MakeSavingAccount() { ... }
  public static BankAccount MakeChequingAccount() { ... }
}

This way, consumers do not worry about the type of BankAccount and cannot nest their own subclasses.

Is there an equivalent way to do this in C++?

Upvotes: 2

Views: 155

Answers (2)

Chris Drew
Chris Drew

Reputation: 15334

Firstly, I'm a little bit wary of a design that couples the interface to the implementation and would prefer to have the subclasses and factories separate from the BankAccount interface but let's assume you want it that way.

Be careful with nested classes in C++, before C++11 they had no special access rights to the outer class, but you could achieve a similar thing with friend classes.

With C++11 we get the final specifier that allows us to prevent subclassing.

Here is the version using nested classes, using friend classes instead would be very similar:

#include <memory>

class BankAccount {
 private:
  class SavingsAccount;
  class ChequingAccount;
  BankAccount() = default;  // prevent third-party subclassing
 public:
  virtual ~BankAccount() {}
  static std::unique_ptr<BankAccount> makeSavingsAccount();
  static std::unique_ptr<BankAccount> makeChequingAccount();  
};

class BankAccount::SavingsAccount final : public BankAccount { };

class BankAccount::ChequingAccount final : public BankAccount { };

std::unique_ptr<BankAccount>
BankAccount::makeSavingsAccount() {
  return std::make_unique<SavingsAccount>();
}

std::unique_ptr<BankAccount>
BankAccount::makeChequingAccount() {
  return std::make_unique<ChequingAccount>();
}

int main() {
   auto savings = BankAccount::makeSavingsAccount();
   auto chequing = BankAccount::makeChequingAccount();
}

Live demo

The factory methods have to return a pointer, preferably a smart-pointer like unique_ptr. unique_ptr can be converted to shared_ptr if required.

Upvotes: 1

Dave Doknjas
Dave Doknjas

Reputation: 6542

This is straight forward in C++:

class BankAccount
{
private:
    BankAccount(){}
    class SavingsAccount;
    class ChequingAccount;

public:
    static BankAccount MakeSavingAccount();
    static BankAccount MakeChequingAccount();
};

class BankAccount::SavingsAccount final : public BankAccount
{
};

class BankAccount::ChequingAccount final : public BankAccount
{
};

BankAccount BankAccount::MakeSavingAccount()
{
    ...
}

BankAccount BankAccount::MakeChequingAccount()
{
    ...
}

Upvotes: 0

Related Questions