为了向界面用户隐藏实现细节并避免广泛使用模板化函数,我想到了以下概念:
// 数据.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_
// 数据.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>;
// 列表.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_
// 列表.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
不会对此代码发出警告,它会打印预期值。