Reputation: 1392
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
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();
}
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
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