C++ 对自定义函数的理解
创建一个位字段的UserArray,其声明如下:数组占用的大小将小于普通数组。假设我们需要一个包含20个标志(TRUE/FALSE)的数组。C++ 对自定义函数的理解,c++,templates,user-defined-functions,C++,Templates,User Defined Functions,创建一个位字段的UserArray,其声明如下:数组占用的大小将小于普通数组。假设我们需要一个包含20个标志(TRUE/FALSE)的数组。bool标志[20]将占用20字节的内存,而UserArray将占用4字节的内存 使用类模板创建用户数组 使用逐位运算符打包阵列 还应实施平等操作 template<class T,int W,int L,int H>//i have used template<class T>
bool标志[20]
将占用20字节的内存,而UserArray
将占用4字节的内存
- 使用类模板创建用户数组李>
- 使用逐位运算符打包阵列
- 还应实施平等操作
template<class T,int W,int L,int H>//i have used template<class T> //but never used such way class UserArray{ //.... }; typedef UserArray<bool,4,0,20> MyType;
template//我用过这个模板 //但从未用过这种方式 类UserArray{ //.... }; typedef UserArray MyType;
- T=数组元素的类型
- W=数组元素的宽度,0
- L=数组索引的下限(最好为零)
- H=数组索引的上限
int main() {
MyType Display; //typedef UserArray<T,W,L,H> MyType; defined above
Display[0] = FALSE; //need to understand that how can we write this?
Display[1] = TRUE; //need to understand that how can we write this?
//assert(Display[0]);//commented once, need to understand above code first
//assert(Display[1]);//commented once..
//cout << “Size of the Display” << sizeof(Display);//commented once..
}
intmain(){
MyType显示;//typedef UserArray MyType;已在上面定义
Display[0]=FALSE;//需要了解我们如何编写这个?
Display[1]=TRUE;//需要了解如何编写此代码?
//assert(Display[0]);//注释一次,需要先理解上面的代码
//断言(显示[1]);//注释一次。。
//coutW
、L
和H
是非类型模板参数。您可以使用常量值实例化模板(在编译时),例如:
template <int N>
class MyArray
{
public:
float data[N];
void print() { std::cout << "MyArray of size " << N << std::endl; }
};
MyArray<7> foo;
MyArray<8> bar;
foo.print(); // "MyArray of size 7"
bar.print(); // "MyArray of size 8"
模板
类MyArray
{
公众:
浮点数据[N];
void print(){std::coutW
、L
和H
是非类型模板参数。您可以使用常量值实例化模板(在编译时),例如:
template <int N>
class MyArray
{
public:
float data[N];
void print() { std::cout << "MyArray of size " << N << std::endl; }
};
MyArray<7> foo;
MyArray<8> bar;
foo.print(); // "MyArray of size 7"
bar.print(); // "MyArray of size 8"
模板
类MyArray
{
公众:
浮点数据[N];
void print(){std::cout这并不简单,特别是因为可以使用可变的位宽度
有一个常量字符位
,它是一个字节中的位数。通常是8,但可以大于8(但不能小于8)
我建议每个字节的元素数为CHAR\u-BIT/W
。例如,如果宽度为3
,CHAR\u-BIT
为8
,这可能会浪费一些位,但这已经够复杂了
然后,您需要定义运算符[]
来访问元素,并且可能需要进行一些修改来完成此操作。对于运算符[]的非常量版本
,当一个字节中有多个元素时,可能必须返回某种代理对象,并重写其运算符=
,以便将其写回数组中的相应位置
不过,这是一个很好的练习来解决这个问题。这并不简单,特别是当您可以使用可变的位宽度时
有一个常量字符位
,它是一个字节中的位数。通常是8,但可以大于8(但不能小于8)
我建议每个字节的元素数为CHAR\u-BIT/W
。例如,如果宽度为3
,CHAR\u-BIT
为8
,这可能会浪费一些位,但这已经够复杂了
然后,您需要定义运算符[]
来访问元素,并且可能需要进行一些修改来完成此操作。对于运算符[]的非常量版本
,当一个字节中有多个元素时,可能必须返回某种代理对象,并重写其运算符=
,以便将其写回数组中的相应位置
不过,弄清楚这一点是一个很好的练习。这里有一些代码实现了您所要求的功能,但下限固定为0。它还显示了运算符地址的一个罕见用例。如果您愿意,您可以更进一步,使此容器与STL算法兼容
#include <iostream>
#include <limits.h>
#include <stddef.h>
template<class T, size_t WIDTH, size_t SIZE>
class UserArray;
template<class T, size_t WIDTH, size_t SIZE>
class UserArrayProxy;
template<class T, size_t WIDTH, size_t SIZE>
class UserArrayAddressProxy
{
public:
typedef UserArray<T, WIDTH, SIZE> array_type;
typedef UserArrayProxy<T, WIDTH, SIZE> proxy_type;
typedef UserArrayAddressProxy<T, WIDTH, SIZE> this_type;
UserArrayAddressProxy(array_type& a_, size_t i_) : a(a_), i(i_) {}
UserArrayAddressProxy(const this_type& x) : a(x.a), i(x.i) {}
proxy_type operator*() { return proxy_type(a, i); }
this_type& operator+=(size_t n) { i += n; return *this; }
this_type& operator-=(size_t n) { i -= n; return *this; }
this_type& operator++() { ++i; return *this; }
this_type& operator--() { --i; return *this; }
this_type operator++(int) { this_type x = *this; ++i; return x; }
this_type operator--(int) { this_type x = *this; --i; return x; }
this_type operator+(size_t n) const { this_type x = *this; x += n; return x; }
this_type operator-(size_t n) const { this_type x = *this; x -= n; return x; }
bool operator==(const this_type& x) { return (&a == &x.a) && (i == x.i); }
bool operator!=(const this_type& x) { return !(*this == x); }
private:
array_type& a;
size_t i;
};
template<class T, size_t WIDTH, size_t SIZE>
class UserArrayProxy
{
public:
static const size_t BITS_IN_T = sizeof(T) * CHAR_BIT;
static const size_t ELEMENTS_PER_T = BITS_IN_T / WIDTH;
static const size_t NUMBER_OF_TS = (SIZE - 1) / ELEMENTS_PER_T + 1;
static const T MASK = (1 << WIDTH) - 1;
typedef UserArray<T, WIDTH, SIZE> array_type;
typedef UserArrayProxy<T, WIDTH, SIZE> this_type;
typedef UserArrayAddressProxy<T, WIDTH, SIZE> address_proxy_type;
UserArrayProxy(array_type& a_, int i_) : a(a_), i(i_) {}
this_type& operator=(T x)
{
a.write(i, x);
return *this;
}
address_proxy_type operator&() { return address_proxy_type(a, i); }
operator T()
{
return a.get(i);
}
private:
array_type& a;
size_t i;
};
template<class T, size_t WIDTH, size_t SIZE>
class UserArray
{
public:
typedef UserArrayAddressProxy<T, WIDTH, SIZE> ptr_t;
static const size_t BITS_IN_T = sizeof(T) * CHAR_BIT;
static const size_t ELEMENTS_PER_T = BITS_IN_T / WIDTH;
static const size_t NUMBER_OF_TS = (SIZE - 1) / ELEMENTS_PER_T + 1;
static const T MASK = (1 << WIDTH) - 1;
T operator[](size_t i) const
{
return get(i);
}
UserArrayProxy<T, WIDTH, SIZE> operator[](size_t i)
{
return UserArrayProxy<T, WIDTH, SIZE>(*this, i);
}
friend class UserArrayProxy<T, WIDTH, SIZE>;
private:
void write(size_t i, T x)
{
T& element = data[i / ELEMENTS_PER_T];
int offset = (i % ELEMENTS_PER_T) * WIDTH;
x &= MASK;
element &= ~(MASK << offset);
element |= x << offset;
}
T get(size_t i)
{
return (data[i / ELEMENTS_PER_T] >> ((i % ELEMENTS_PER_T) * WIDTH)) & MASK;
}
T data[NUMBER_OF_TS];
};
int main()
{
typedef UserArray<int, 6, 20> myarray_t;
myarray_t a;
std::cout << "Sizeof a in bytes: " << sizeof(a) << std::endl;
for (size_t i = 0; i != 20; ++i) { a[i] = i; }
for (size_t i = 0; i != 20; ++i) { std::cout << a[i] << std::endl; }
std::cout << "We can even use address_of operator: " << std::endl;
for (myarray_t::ptr_t e = &a[0]; e != &a[20]; ++e) { std::cout << *e << std::endl; }
}
#包括
#包括
#包括
模板
类用户数组;
模板
类UserArrayProxy;
模板
类UserArrayAddressProxy
{
公众:
typedef UserArray_类型;
typedef UserArrayProxy_类型;
typedef UserArrayAddressProxy此_类型;
UserArrayAddressProxy(数组类型和大小):a(a),i(i){
UserArrayAddressProxy(const this_type&x):a(x.a),i(x.i){
代理类型运算符*(){返回代理类型(a,i);}
this_type&运算符+=(size_t n){i+=n;返回*this;}
this_type&运算符-=(size_t n){i-=n;返回*this;}
this_type&operator++(){++i;返回*this;}
this_type&运算符--(){--i;返回*this;}
this_type运算符++(int){this_type x=*this;++i;返回x;}
this_type运算符--(int){this_type x=*this;--i;返回x;}
this_type操作符+(size_t n)const{this_type x=*this;x+=n;返回x;}
this_-type运算符-(size_t n)const{this_-type x=*this;x-=n;返回x;}
布尔运算符==(const this_type&x){return(&a==&x.a)&&(i==x.i)}
布尔运算符!=(const this_type&x){return!(*this==x);}
私人:
数组类型&a;
尺寸i;
};
模板
类UserArrayProxy
{
公众:
静态常量大小\u t位\u IN\u t=sizeof(t)*字符位;
静态常量大小\u t元素每\u t=位\u IN\u t/宽度;
静态常量大小\u t数量\u t=(大小-1)/每个元素\u t+1;
static const T MASK=(1这里有一些代码实现了您所要求的功能,但下限固定为0。它还显示了运算符地址_的一个罕见用例。如果您愿意,您可以更进一步,使此容器与STL算法兼容
#include <iostream>
#include <limits.h>
#include <stddef.h>
template<class T, size_t WIDTH, size_t SIZE>
class UserArray;
template<class T, size_t WIDTH, size_t SIZE>
class UserArrayProxy;
template<class T, size_t WIDTH, size_t SIZE>
class UserArrayAddressProxy
{
public:
typedef UserArray<T, WIDTH, SIZE> array_type;
typedef UserArrayProxy<T, WIDTH, SIZE> proxy_type;
typedef UserArrayAddressProxy<T, WIDTH, SIZE> this_type;
UserArrayAddressProxy(array_type& a_, size_t i_) : a(a_), i(i_) {}
UserArrayAddressProxy(const this_type& x) : a(x.a), i(x.i) {}
proxy_type operator*() { return proxy_type(a, i); }
this_type& operator+=(size_t n) { i += n; return *this; }
this_type& operator-=(size_t n) { i -= n; return *this; }
this_type& operator++() { ++i; return *this; }
this_type& operator--() { --i; return *this; }
this_type operator++(int) { this_type x = *this; ++i; return x; }
this_type operator--(int) { this_type x = *this; --i; return x; }
this_type operator+(size_t n) const { this_type x = *this; x += n; return x; }
this_type operator-(size_t n) const { this_type x = *this; x -= n; return x; }
bool operator==(const this_type& x) { return (&a == &x.a) && (i == x.i); }
bool operator!=(const this_type& x) { return !(*this == x); }
private:
array_type& a;
size_t i;
};
template<class T, size_t WIDTH, size_t SIZE>
class UserArrayProxy
{
public:
static const size_t BITS_IN_T = sizeof(T) * CHAR_BIT;
static const size_t ELEMENTS_PER_T = BITS_IN_T / WIDTH;
static const size_t NUMBER_OF_TS = (SIZE - 1) / ELEMENTS_PER_T + 1;
static const T MASK = (1 << WIDTH) - 1;
typedef UserArray<T, WIDTH, SIZE> array_type;
typedef UserArrayProxy<T, WIDTH, SIZE> this_type;
typedef UserArrayAddressProxy<T, WIDTH, SIZE> address_proxy_type;
UserArrayProxy(array_type& a_, int i_) : a(a_), i(i_) {}
this_type& operator=(T x)
{
a.write(i, x);
return *this;
}
address_proxy_type operator&() { return address_proxy_type(a, i); }
operator T()
{
return a.get(i);
}
private:
array_type& a;
size_t i;
};
template<class T, size_t WIDTH, size_t SIZE>
class UserArray
{
public:
typedef UserArrayAddressProxy<T, WIDTH, SIZE> ptr_t;
static const size_t BITS_IN_T = sizeof(T) * CHAR_BIT;
static const size_t ELEMENTS_PER_T = BITS_IN_T / WIDTH;
static const size_t NUMBER_OF_TS = (SIZE - 1) / ELEMENTS_PER_T + 1;
static const T MASK = (1 << WIDTH) - 1;
T operator[](size_t i) const
{
return get(i);
}
UserArrayProxy<T, WIDTH, SIZE> operator[](size_t i)
{
return UserArrayProxy<T, WIDTH, SIZE>(*this, i);
}
friend class UserArrayProxy<T, WIDTH, SIZE>;
private:
void write(size_t i, T x)
{
T& element = data[i / ELEMENTS_PER_T];
int offset = (i % ELEMENTS_PER_T) * WIDTH;
x &= MASK;
element &= ~(MASK << offset);
element |= x << offset;
}
T get(size_t i)
{
return (data[i / ELEMENTS_PER_T] >> ((i % ELEMENTS_PER_T) * WIDTH)) & MASK;
}
T data[NUMBER_OF_TS];
};
int main()
{
typedef UserArray<int, 6, 20> myarray_t;
myarray_t a;
std::cout << "Sizeof a in bytes: " << sizeof(a) << std::endl;
for (size_t i = 0; i != 20; ++i) { a[i] = i; }
for (size_t i = 0; i != 20; ++i) { std::cout << a[i] << std::endl; }
std::cout << "We can even use address_of operator: " << std::endl;
for (myarray_t::ptr_t e = &a[0]; e != &a[20]; ++e) { std::cout << *e << std::endl; }
}
#包括
#包括
#包括
模板
类用户数组;
模板
类UserArrayProxy;
模板
类UserArrayAddressProxy
{
公众:
typedef UserArray_类型;
typedef UserArrayProxy_类型;
typedef UserArrayAddressProxy此_类型;
UserArrayAddressProxy(数组类型和大小):a(a),i(i){
UserArrayAddressProxy(const this_type&x):a(x.a),i(x.i){
代理类型