인터페이스의 사용자의 구현 세부 정보를 숨기려면 내가 다음과 같은 개념으로 생각 플릿 기능의 대폭적인 사용을 방지하기 위해 :캐스트
// data.h
#ifndef DATA_H_
#define DATA_H_
#include <cstddef>
template <size_t N = 0>
class Data
{
public:
const size_t n;
size_t values[N];
Data<N>();
};
#endif // DATA_H_
을
// data.cpp
#include "data.h"
template <size_t N> Data<N>::Data()
:
n(N),
values()
{
for (size_t i = 0; i < n; ++i)
{
values[i] = i;
}
}
template class Data<1u>;
template class Data<2u>;
// list.h
#ifndef LIST_H_
#define LIST_H_
#include <cstddef>
#include <memory>
class List
{
private:
std::shared_ptr<void> data;
public:
List(const size_t);
void printData() const;
};
#endif // LIST_H_
// list.cpp
#include "list.h"
#include <iostream>
#include <stdexcept>
#include "data.h"
List::List(const size_t n)
:
data()
{
switch (n)
{
case 1u:
data = std::static_pointer_cast<void>(std::make_shared<Data<1u>>());
break;
case 2u:
data = std::static_pointer_cast<void>(std::make_shared<Data<2u>>());
break;
default:
throw std::runtime_error("not instantiated..");
}
}
void List::printData() const
{
auto obj = std::static_pointer_cast<Data<>>(data); // my question is about this
std::cout << obj->n << ": ";
for (size_t i = 0; i < obj->n; ++i)
{
std::cout << obj->values[i] << " ";
}
std::cout << "\n";
}
// MAIN.CPP
#include "list.h"
int main()
{
for (size_t i = 1; i <= 2; ++i)
{
try
{
List list(i);
list.printData();
}
catch (...)
{
return 1;
}
}
}
좀이 같은 끔찍한 디자인을 생각할 수 있다는 것을 알고있다. 당신이 화려한 대안을 가지고 있지 않다면, 여기에서 이것을 토론하지 마십시오.
제 질문은 auto obj = std::static_pointer_cast<Data<>>(data);
의 List::printData()
에 대한 것입니다. 그것은 안전하지 못하다고 느낍니다. 올바른 인스턴스 생성이 사용됩니까? g++-4.6.3
은이 코드에 대해 경고를 표시하지 않으며 예상 값을 인쇄합니다.
데이터 클래스의'const size_t n'이 완전히 불필요하다는 것을 알기를 바랍니다. ** 'N' **과 같은 템플릿 매개 변수 목록의 일부로 값을가집니다. – WhozCraig
@WhozCraig'obj-> n '은 어떨까요? 템플릿 매개 변수를 사용하여이를 수행하는 방법은 무엇입니까? – stefan
std :: static_pointer_cast > 항상 데이터로 전송됩니다 <0> ... 그게 당신이 묻는 것입니까? –