我有一个课程:
import java.time.{ZonedDateTime, ZonedOffset}
// val yourTimeZoneOffset = ZoneOffset.ofHoursMinutesSeconds(hour, minute, second)
// for example IST or Indian Standard Time has an offset of "+05:30:00" hrs
val istOffset = ZoneOffset.ofHoursMinutesSeconds(5, 30, 0)
// istOffset: java.time.ZoneOffset = +05:30
// time representation in IST
val zonedDateTimeIst = ZonedDateTime.now(istOffset)
// zonedDateTimeIst: java.time.ZonedDateTime = 2016-09-29T20:14:48.048+05:30
val year = zonedDateTimeIst.getYear
// year: Int = 2016
val month = zonedDateTimeIst.getMonth
// month: java.time.Month = SEPTEMBER
val dayOfMonth = zonedDateTimeIst.getDayOfMonth
// dayOfMonth: Int = 29
val df1 = DateTimeFormatter.ofPattern("yyyy - MM - dd")
val df2 = DateTimeFormatter.ofPattern("yyyy/MM/dd")
// df1: java.time.format.DateTimeFormatter = Value(YearOfEra,4,19,EXCEEDS_PAD)' ''-'' 'Value(MonthOfYear,2)' ''-'' 'Value(DayOfMonth,2)
// df2: java.time.format.DateTimeFormatter = Value(YearOfEra,4,19,EXCEEDS_PAD)'/'Value(MonthOfYear,2)'/'Value(DayOfMonth,2)
val dateString1 = zonedDateTimeIst.format(df1)
// dateString1: String = 2016 - 09 - 29
val dateString2 = zonedDateTimeIst.format(df2)
// dateString2: String = 2016/09/29
和我正在做的其中一个功能:
private:
uint32_t *data;
这很好用。现在我想让它更灵活,所以我想让foo()成为一个模板:
void foo() {
data = new uint32_t[size];
}
我尝试使用它:
template<typename T>
T foo() {
data = new T[size];
}
但编译失败说:
class.foo<uint64_t>();
有可能做那样的事吗?我试着宣布
error: cannot convert 'long long unsigned int*' to 'unsigned int*' in assignment
并编译,但后来我不能
void *data;
这就是我需要传递类型的原因。
修改
感谢您的回复,在查看您的答案后,我想添加一些内容。
另一个想法: 默认模板类型可能是一个很好的折衷方案,有没有办法创建一个我以后不必使用的类:
sizeof(data[1]);
但仍然:
Class<> my;
如果需要:
Class my;
答案 0 :(得分:2)
不是将您的函数转换为模板,而是将您的类转换为模板:
template <class T>
class myclass {
private:
T *data;
public:
myclass(size_t size) : data(new T[size]) {
}
... // Add copy constructor, assignment operator, and a destructor
// to properly manage the pointer. See "rule of three" for more info.
};
这样,数组元素的类型成为类的类型的一部分,让您的成员函数与data
一起使用,而无需任何其他类型的转换。
请注意,在类中使用原始数组指针在内存管理方面存在重大责任。你最好使用std::vector<T>
。
答案 1 :(得分:1)
您可以考虑将整个班级设为模板,如下所示:
template <typename T>
class Foo
{
private:
T *data;
public:
Foo(size_t size_):
data{new T[size]}
{
}
~Foo()
{
delete[] data;
}
};
这里的实施只是部分的。请参阅rule of 3, 5, 0。
或使用托管指针:
template <typename T>
class Foo
{
private:
std::unique_ptr<T[]> data;
size_t size;
public:
Foo(size_t size_):
data{std::make_unique<T[]>(size_)},
size(size_)
{
}
~Foo()
{
// no need to call delete, unique_ptr will do it
}
};
但是一旦你来到这里,根据你的使用情况,替代方案可能更可取,例如std::vector
:
std::vector<uint64_t> v(size);
// ...
std::cout << v.size() << std::endl;
修改强>
根据您提供的其他信息,以下设计可能更适合您的需求:
class Base
{
public:
virtual void* get_data() {
return nullptr;
}
virtual size_t get_size() {
return 0;
}
};
template<typename T>
class Foo : public Base
{
private:
T* data;
size_t size;
public:
Foo(size_t size_):
data{new T[size_]},
size(size_) {}
~Foo() {
delete[] this->data; // same remark as above about rule of 5
}
virtual void* get_data() overriden {
return this->data;
}
virtual size_t get_size() overriden {
return this->size;
}
};
具有以下用途:
std::unique_ptr<Base> my_without_data =
std::make_unique<Base>();
std::unique_ptr<Base> my_with_data =
std::make_unique<Foo<type>>(size);
请注意,在第二次通话中,std::make_unique
会返回一个unique_ptr<Foo<type>>
,其中有一个适当的删除者,正在调用Foo<type>
的析构函数。即使my_with_data
的析构函数未声明为虚拟,也会在分配给Foo<type>
时调用删除者并调用Base
的析构函数。
我在这里选择了Base
中带有虚拟方法的设计来访问data
。根据您的实际使用情况,可以使用其他方式。
答案 2 :(得分:1)
将您的整个班级转换为模板类
template<typename T>
class Container {
public:
Container() :
data(NULL)
{}
~Container() {
if (data) {
delete [] data;
}
}
T* foo(int size) {
if (data) {
delete [] data;
}
data = new T[size];
return data;
}
private:
T *data;
};