C ++에서 동일한 클래스에 대해 서로 다른 유형을 정의하는 방법
동일한 구현을 공유하지만 C ++에서 여전히 다른 유형 인 여러 유형을 갖고 싶습니다.
간단한 예제로 내 질문을 설명하기 위해 Apples, Oranges 및 Bananas에 대한 클래스를 만들고 싶습니다. 모두 동일한 작업과 동일한 구현을 가지고 있습니다. 유형 안전성 덕분에 오류를 피하고 싶기 때문에 다른 유형을 갖기를 바랍니다.
class Apple {
int p;
public:
Apple (int p) : p(p) {}
int price () const {return p;}
}
class Banana {
int p;
public:
Banana (int p) : p(p) {}
int price () const {return p;}
}
class Orange ...
코드를 복제하지 않기 위해 기본 클래스 Fruit을 사용하고 상속 할 수있는 것처럼 보입니다.
class Fruit {
int p;
public:
Fruit (int p) : p(p) {}
int price () const {return p;}
}
class Apple: public Fruit {};
class Banana: public Fruit {};
class Orange: public Fruit {};
그러나 생성자는 상속되지 않으므로 다시 작성해야합니다.
유형이 다른 동일한 클래스를 쉽게 가질 수있는 메커니즘 (typedef, 템플릿, 상속 ...)이 있습니까?
일반적인 기술은 템플릿 인수가 고유 한 유형을 만들기 위해 단순히 고유 한 토큰 ( "태그") 역할을하는 클래스 템플릿을 갖는 것입니다.
template <typename Tag>
class Fruit {
int p;
public:
Fruit(int p) : p(p) { }
int price() const { return p; }
};
using Apple = Fruit<struct AppleTag>;
using Banana = Fruit<struct BananaTag>;
태그 클래스는 정의 할 필요조차 없으며 고유 한 유형 이름 을 선언 하는 것으로 충분합니다 . 이것은 태그가 실제로 템플릿의 어느 곳에서나 사용 되기 때문에 작동합니다 . 그리고 템플릿 인수 목록 (@Xeo에 대한 모자 팁) 내 에서 유형 이름을 선언 할 수 있습니다 .
using
구문은 C ++ 11이다. C ++ 03을 고수하는 경우 대신 다음을 작성하십시오.
typedef Fruit<struct AppleTag> Apple;
If the common functionality takes up a lot of code this unfortunately introduces quite a lot of duplicate code in the final executable. This can be prevented by having a common base class implementing the functionality, and then having a specialisation (that you actually instantiate) that derives from it.
Unfortunately, that requires you to re-implement all non-inheritable members (constructors, assignment …) which adds a small overhead itself – so this only makes sense for large classes. Here it is applied to the above example:
// Actual `Fruit` class remains unchanged, except for template declaration
template <typename Tag, typename = Tag>
class Fruit { /* unchanged */ };
template <typename T>
class Fruit<T, T> : public Fruit<T, void> {
public:
// Should work but doesn’t on my compiler:
//using Fruit<T, void>::Fruit;
Fruit(int p) : Fruit<T, void>(p) { }
};
using Apple = Fruit<struct AppleTag>;
using Banana = Fruit<struct BananaTag>;
Use templates, and use a trait per fruit, for example:
struct AppleTraits
{
// define apple specific traits (say, static methods, types etc)
static int colour = 0;
};
struct OrangeTraits
{
// define orange specific traits (say, static methods, types etc)
static int colour = 1;
};
// etc
Then have a single Fruit
class which is typed on this trait eg.
template <typename FruitTrait>
struct Fruit
{
// All fruit methods...
// Here return the colour from the traits class..
int colour() const
{ return FruitTrait::colour; }
};
// Now use a few typedefs
typedef Fruit<AppleTraits> Apple;
typedef Fruit<OrangeTraits> Orange;
May be slightly overkill! ;)
- C++11 would allow constructor inheritance: Using C++ base class constructors?
- Otherwise, you can use templates to achieve the same, e.g.
template<class Derived> class Fruit;
There is also BOOST_STRONG_TYPEDEF.
참고URL : https://stackoverflow.com/questions/14232293/how-to-define-different-types-for-the-same-class-in-c
'Programing' 카테고리의 다른 글
git에서 커밋 사이를 앞뒤로 어떻게 이동합니까? (0) | 2020.09.24 |
---|---|
Gradle에 새 소스 세트를 어떻게 추가합니까? (0) | 2020.09.24 |
C #에서 Java System.currentTimeMillis ()에 해당 (0) | 2020.09.23 |
중복이없는 난수 만들기 (0) | 2020.09.23 |
foreach (항목의 T 항목) 전에 if (항목! = null)이 불필요합니까? (0) | 2020.09.23 |