Название немного расплывчато, но я не могу придумать лучшую формулировку, вот предложение:
class A
{
public:
A();
A( const PropertyB& b );
PropertyA GetPropertyA();
PropertyB GetPropertyB();
SetPropertyA( const PropertyA& b );
SetPropertyB( const PropertyB& b );
//assignment not allowed
};
Предположим, я хочу использовать std :: vector , но,имеет смысл иметь вектор A, если все его элементы имеют одинаковое значение для PropertyB.Текущее решение состоит в том, чтобы предоставить метод, подобный контролю, для создания такого массива, который гарантирует, что все элементы возвращаемого массива имеют одинаковое значение для PropertyB, и метод, который проверяет, так ли это:
Array MakeArray( size_t, const PropertyB& );
bool CheckIfArrayIsSane( const Array& );
Таким образом, пользователи могут по-прежнему вызывать SetPropertyB () для элементов, но у них есть утилита, чтобы проверить это и выручить, если кто-то это сделал:
Array x( MakeArray( 3, someValue ) );
x.SetPropertyA( aaa ); //should be allowed
x.SetPropertyB( someOtherValue ); //should NOT be allowed
//somewhat further in the program
if( !CheckIfArrayIsSane( x ) )
throw InsaneArrayExcpetion();
Хотя это работает, оно подвержено ошибкам, так как это трудно заставитьпроверяйте везде и не забывайте об этом и загромождайте код проверками.
Приближения, которые не работают:
Еще один навязчивый подход, который бы работал, но чувствовал себя немного не элегантно и нуждался в дополнительных функциях для преобразования между ними и т.д .:
class AWithFixedPropertyB
{
public:
A( const PropertyB& b );
PropertyA GetPropertyA();
PropertyB GetPropertyB();
SetPropertyA( const PropertyA& b );
};
class A : public AWithFixedPropertyB
{
public:
//contrcutors etc
SetPropertyB( const PropertyB& b );
};
//ok, users cannot modify property B in this Array
typedef std::vector< AWithFixedPropertyB > Array;
Какое было бы самое элегантное решение для этой проблемы?