2014-10-09 3 views
2

Я изучаю C++, исходя из C#. В C#, может быть классы, такие как:С ++ эквивалент C# вложенных частных классов

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() { ... } 
} 

Таким образом, потребители не беспокоиться о типе BankAccount и не может вкладывать свои собственные подклассов.

Есть ли эквивалентный способ сделать это на C++?

+0

ключевое слово 'final' может вам помочь (C++ 11) – OMGtechy

+3

Вы никогда не собираетесь полностью выровнять семантику двух разных языков. Также это может не иметь смысла на целевом языке для этого. Я рекомендую вам не пытаться просматривать C++ через очки C#. Забудьте о том, что вы знаете о C#, и изучите C++ с нуля. – Galik

+0

придерживаться C# и использовать небезопасное ключевое слово. если вы не знаете, что делаете с помощью c/C++, вы действительно можете открыть себя до недостатков безопасности. – RadioSpace

ответ

1

Во-первых, я немного настороженно относятся к конструкции, которая соединяет интерфейс для реализации и предпочли бы иметь подклассы и заводы отдельно от BankAccount интерфейс, но давайте предположим, что вы так хотите.

Будьте осторожны с вложенными классами на C++, до того, как C++ 11 у них не было специальных прав доступа к внешнему классу, но вы могли бы достичь аналогичной вещи с классами друзей.

С C++ 11 мы получаем спецификатор final, который позволяет нам предотвращать подклассы.

Вот версия с использованием вложенных классов, используя друг классы вместо бы очень похоже:

#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

Метода фабричной должна возвращать указатель, предпочтительно смарт-указатель, как unique_ptr. unique_ptr может быть преобразован в shared_ptr, если требуется.

0

Это прямо вперед в 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() 
{ 
    ... 
} 
+0

Как реализованы заводские методы? – cm007

+0

Почти идентично C#. В классе «BankAccount». –

+0

@ChrisDrew: частный конструктор тривиален в C++ - я просто воспроизвел код C++, который, возможно, не был очевиден. –

Смежные вопросы