精华内容
下载资源
问答
  • 模板类的静态成员变量

    千次阅读 2013-09-16 14:16:50
    我自己写了一个简易的空间适配器代码如下,后来发现,不同类型的类模板共享的静态成员变量不是同一块。 这可以通过查看不同类型类模板静态成员的地址,地址相同,表示共享的是同一块,不同则表示不是同一块。 cout...

    我自己写了一个简易的空间适配器代码如下,后来发现,不同类型的类模板共享的静态成员变量不是同一块

    这可以通过查看不同类型类模板静态成员的地址,地址相同,表示共享的是同一块,不同则表示不是同一块。

    cout<<"address="<<&Second_alloc<char>::free_list[i]<<endl;

    cout<<"address="<<&Second_alloc<int>::free_list[i]<<endl;

    也就是说:类模板的静态成员变量是所有同类型的类模板实例共享的一块数据。

    #include<iostream>
    #include<cstddef>
    using namespace std;


    //第一级空间配置器
    template<class T>
    class First_alloc{


    public:
    static T *allocate(size_t size)
    {
    void *result = malloc(size * sizeof(T));
    return (T *)result;
    }


    static void deallocate(void *p)
    {
    free(p);
    }


    };


    //第二级空间配置器
    template<class T>
    class Second_alloc{
    private:
    enum{ ALIGN = 8, MAX_BYTES = 128, NUMBER = MAX_BYTES / ALIGN};


    //将bytes调整为8的倍数
    static size_t ROUND_UP(size_t bytes)
    {
    return ((bytes + ALIGN - 1) & ~ (ALIGN -1));
    }


    static int FREELIST_INDEX(size_t bytes)
    {
    return ((bytes  + ALIGN -1) / ALIGN - 1 );
    }

    static char *start_free;
    static char *end_free;
    static char *refill(size_t n);
    static char *chunk_alloc(size_t n, int& nobj);
    public:
    struct obj{
    char *address;
    obj *next;
    };
        static obj *free_list[NUMBER];
    public:
    static T *allocate(size_t n);
    static void deallocate(void *p, int size);


    };


    template<class T>
    typename Second_alloc<T>::obj *
    Second_alloc<T>::free_list[NUMBER] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};


    template<class T>
    char *Second_alloc<T>::start_free = 0;


    template<class T>
    char *Second_alloc<T>::end_free =0;


    template<class T>
    char * Second_alloc<T>::chunk_alloc(size_t n, int& nobj)
    {
    size_t bytes_to_need = n * nobj;
    size_t bytes_left = end_free - start_free;
    char *result;
    if(bytes_left >= bytes_to_need)
    {
    result = start_free;
    start_free += bytes_to_need;
    return result;
    }
    else if(bytes_left >= n)
    {
    nobj = bytes_left/n;
    bytes_to_need = n * nobj;
    result = start_free;
    start_free += bytes_to_need;
    return result;
    }
    else
    {
    if(bytes_left > 0)
    {
    obj **my_free_list = free_list + FREELIST_INDEX(bytes_left);
    obj * tmp = (obj *)start_free;
    tmp->address = start_free;
    tmp->next = *my_free_list;
    *my_free_list = tmp;
    }
    start_free = (char *)malloc(bytes_to_need * 2);
    result = start_free;
    start_free += bytes_to_need;
    end_free = start_free + bytes_to_need;
    return chunk_alloc(n, nobj);
    }
    }


    template<class T>
    char * Second_alloc<T>::refill(size_t n)
    {
    int nobj = 20;
    char *chunk = chunk_alloc(n, nobj);
    char *result =chunk;


    obj **my_free_list;
    my_free_list = free_list + FREELIST_INDEX(n);
    *my_free_list = (obj *)(chunk + n);


    int i;
    char *address = chunk + n;
    obj *current_obj = *my_free_list;
    for(i=1; ;i++)
    {
    current_obj->address = address;
    if(nobj -1 == i)
    {
    current_obj->next = 0;
    break;
    }
    else
    {
    current_obj->next = (obj *)(address + n);
    address +=n;
    current_obj = current_obj->next;
    }
    }
    return result;
    }
    template<class T>
    T *Second_alloc<T>::allocate(size_t n)
    {
    size_t total_bytes = sizeof(T) * n;
    if(total_bytes > MAX_BYTES)
    {
    return First_alloc<T>::allocate(total_bytes);
    }
    else
    {
    obj **my_free_list;
    obj *result;
    my_free_list = free_list + FREELIST_INDEX(total_bytes);
    result = *my_free_list;
    if(result == 0)
    {
    result =(obj *) refill(ROUND_UP(total_bytes));
    return (T *)result;


    }
    else
    {
    *my_free_list = result->next;
    return (T *)result->address;
    }


    }
    }


    template<class T>
    void Second_alloc<T>::deallocate(void *p, int n)
    {
    size_t size = sizeof(T) * n;
    if(size> MAX_BYTES)
    {
    First_alloc<T>::deallocate(p);
    }
    else
    {
    obj **my_free_list = free_list + FREELIST_INDEX(size);
    obj * result = (obj *)p;
    result->address = (char *)p;
    result->next = *my_free_list;
    *my_free_list = result;
    }
    }


    void main()
    {
    int i;
    int size;
    //分配10个整数空间
    size = 10;
    int * q = Second_alloc<int>::allocate(size);
    int *int_head = q;
    for(i = 0; i < size; i++)
    {
    *q = i;
    q++;
    }
    int *int_start = int_head;
    for(i = 0; i< size; i++)
    {
    cout<<*int_start<<endl;
    int_start++;
    }
    cout<<"------------------------------------------------------------------"<<endl;
    for(i = 0; i < 16; i++)
    {
    cout<<"--------"<<i<<"----------------"<<endl;
    cout<<"address="<<&Second_alloc<int>::free_list[i]<<endl;
    if(Second_alloc<int>::free_list[i] != 0)
    {

       Second_alloc<int>::obj * my_free_list = Second_alloc<int>::free_list[i];
    while(1)
    {

    cout<<(int)my_free_list->address<<"-----"<<my_free_list->next<<"-----"<<endl;
    if( my_free_list->next == 0) 
    break;
    else
        my_free_list = my_free_list->next;


    }
    }
    }

    //分配5个字符空间
    size = 5;
    char * p = Second_alloc<char>::allocate(size);
    char * head = p;




    for(i = 0; i < size; i++)
    {
    *p = (char)i;
    p++;
    }
        char *start = head;
        for(i = 0; i < size; i++)
    {
    cout<<*start<<endl;
    start++;
    }


    //分配5个整数空间
    size = 5;
    q = Second_alloc<int>::allocate(size);
    int_head = q;
    for(i = 0; i < size; i++)
    {
    *q = i;
    q++;
    }
    int_start = int_head;
    for(i = 0; i< size; i++)
    {
    cout<<*int_start<<endl;
    int_start++;
    }
    cout<<"------------------------------------------------------------------"<<endl;
    for(i = 0; i < 16; i++)
    {
    cout<<"--------"<<i<<"----------------"<<endl;
    cout<<"address="<<&Second_alloc<int>::free_list[i]<<endl;
    if(Second_alloc<int>::free_list[i] != 0)
    {

       Second_alloc<int>::obj * my_free_list = Second_alloc<int>::free_list[i];
    while(1)
    {

    cout<<(int)my_free_list->address<<"-----"<<my_free_list->next<<"-----"<<endl;
    if( my_free_list->next == 0) 
    break;
    else
        my_free_list = my_free_list->next;


    }
    }
    }
    cout<<"------------------------------------------------------------------"<<endl;
    for(i = 0; i < 16; i++)
    {
    cout<<"--------"<<i<<"----------------"<<endl;
    cout<<"address="<<&Second_alloc<char>::free_list[i]<<endl;
    if(Second_alloc<char>::free_list[i] != 0)
    {

       Second_alloc<char>::obj * my_free_list = Second_alloc<char>::free_list[i];
    while(1)
    {

    cout<<(int)my_free_list->address<<"-----"<<my_free_list->next<<"-----"<<endl;
    if( my_free_list->next == 0) 
    break;
    else
        my_free_list = my_free_list->next;


    }
    }
    }


    }

    展开全文
  • C++的模板可用作结构体、类或模板类成员,在此记录一个例子: #include using std::cout; using std::endl; template class beta{ private: template //将模板类定义放在类的私有变量区域,模板类为私有变量...

    C++的模板可用作结构体、类或模板类成员,在此记录一个例子:

    #include <iostream>
    
    using std::cout;
    using std::endl;
    
    template<typename T>
    class beta{
    private:
    
    	template<typename V>  //将模板类定义放在类的私有变量区域,模板类做为私有变量
    	class hold{
    	private:
    		V val;
    	public:
    		hold(V v){val=v;}
    		void show()const{cout<<val<<endl;}
    		V Value()const{return val;}
    	};
    
    	hold<T> q;  //相当于在beta类中包含了hold类的两个实例,所以下面通过这两个对象使用它们的方法
    	hold<int> n;
    public:
    
    	beta(T t,int i):q(t),n(i){}
    
    	template<typename U>  //模板函数做方法
    	U blab(U u,T t){
    		return (n.value()+q.value())*u/t;
    	}
    
    	void show()const{
    		q.show();
    		n.show();
    	}
    };
    
    int main(){
    	beta<double> guy(3.5,3);
    	guy.show();
    	cout<<guy.blab(10,2.3)<<endl;
    	cout<<"Done\n";
    	return 0;
    }



    展开全文
  • 在C++中如果父类是模板类,直接调用父类成员的话,会报错找不到该变量,其根本原因是因为模板的二次编译机制导致的。 其父类的声明 template &lt;typename T&gt; class SeqList:public List&lt;T&gt...

    在C++中如果父类是模板类,直接调用父类成员的话,会报错找不到该变量,其根本原因是因为模板的二次编译机制导致的。

    其父类的声明

    template <typename T>
    class SeqList:public List<T>{
    protected:
    	T* m_array;//顺序存储空间位置
    	unsigned int length;//当前线性表长度
    public:
    	bool Insert(int i, const T& e);
    	bool Remove(int i);
    	bool Set(int i, const T& e);
    	bool Get(int i, T& e)const;
    	unsigned int Length()const;
    	void Clear();
    
    	//数组访问方式
    	T& operator [](int i);
    	T  operator [](int i)const;
    
    	//设置顺序存储空间容量
    	virtual unsigned int Capacity()const = 0;
    };
    

    将子类写成如下形式:

    template<typename T, int N> //N为数组大小
    class StaticList: public SeqList<T>{
    protected:
    	T space[N];
    public:
    	StaticList(){
    	//找不到父类的两个变量
    		m_array = space;
    		length = 0;
    	}
    
    	unsigned int Capacity() const{
    		return N;
    	}
    };
    

    发现编译器报错说找不到父类中的两个变量m_array,和length。
    经过查询发现,模板要编译两次。

    模板定义阶段(第一阶段):

    只对模板中和模板参数无关的名字进行查找(无视那些有模板参数的部分)。父类是模板类,在第一次编译的时候会被无视掉。
    for instance:
    对于上边的例子:
    StaticList继承自SeqList,在第一次编译的时候编译器会忽略掉SeqList,假装没有看到它,因此SeqList中的成员m_array和length就顺理成章地被忽略了。在StaticList中没有再次定义m_array和length,因此编译器在第一次编译的时候无法找到m_array和length直接报错了。

    模板实例化阶段(第二阶段)

    在第二阶段编译器主要处理带模板参数的部分,所有和模板相关的操作都在该阶段完成。
    给出一个例子,也就是上边问题的解决方法。

    子类:

    template<typename T, int N> //N为数组大小
    class StaticList: public SeqList<T>{
    protected:
    	T space[N];
    public:
    	StaticList(){
    		//父类是模板可以用Base::来调用父类成员
    		SeqList<T>::m_array = space;
    		//父类是模板可以用this来调用父类成员
    		this->length = 0;
    	}
    	unsigned int Capacity() const{
    		return N;
    	}
    };
    

    在这个子类中,在每个成员变量之前加入了Base::或者this指针,通过Base::或者this指针,将成员变量拖到第二阶段进行编译。this指针后边的内容都是成员变量,对于成员变量有两种情况,第一种就是在当前类中定义的变量,会在第一阶段的时候进行检查。当第一阶段无法查找到该成员的时候,就会考虑是不是父类的成员,如果父类是一个模板类,那么需要在第二阶段进行编译,因此编译器会记录下这个成员,等到第二阶段去父类中对该成员进行查找。

    总结:

    对于上述的问题,本质是看子类能不能在实例化之前找到其父类。如果父类是模板类就需要在实例化之后才能找到。

    展开全文
  • C++ 模板类的静态成员变量链接问题

    千次阅读 2012-08-06 14:11:07
    template class A { public: static int const i = 0; ...这样写,运行时会找不到 i 对应的符号,需要改成下面的写法 ...上面只是简单的例子,不能重现,可能是更复杂的使用方式引起的,有空的时候再研究。
    template <typename T>
    class A
    {
    public:
        static int const i = 0;
    };
    


    这样写,运行时会找不到 i  对应的符号,需要改成下面的写法

    template <typename T>
    class A
    {
    public:
        static int const i;
    };
    
    template <typename T>
    int A::i = 0;


    原因不明。上面只是简单的例子,不能重现,可能是更复杂的使用方式引起的,有空的时候再研究。

    展开全文
  • #include <...// 检查 xxxx 是否是T的成员 template <typename T> struct has_member_xxxx { // 如果 &T::xxxx 合法, 本函数就合法 // 下面check<T>(0)优先调用本函数, 返回值是voi...
  • 类模板实例化的每个模板类(每个模板类指的是对于声明时候对模板指定的类型,如List,List中的int,double.)都有自己的类模板静态数据成员,该模板类的所有对象,共享一个静态数据成员。 Tips: (重要)1.模板类的静态...
  • 我现在关心的是如何判断一个中有成员变量成员变量有可能是数组,也可能是其他的。 看了上面关于判断成员函数的文章,理解其原理后,判断是否成员变量,也是差不多的道理,实现起来非常简单。
  • 成员变量 成员变量的修饰 (1) public 公共变量,可被任何包中的任何访问,只有在确认任何外部访问都不会带来不良后果的情况下才将成员声明为公共的,公共变量对任何可见,不具有数据保护功能。 (2)private...
  • c++成员变量和成员函数详解

    千次阅读 2019-04-09 14:38:18
    但是,在定义的时候不能对成员变量赋值,因为只是一种数据类型或者说是一种模板,本身不占用内存空间,而变量的值则需要内存来存储 的成员函数也和普通函数一样,都有返回值和参数列表,它与一般函数的区别是...
  • 在外部取得该地址,然后通过外部指针修改此地址的值,则此私有成员变量的值也改变了,突破了对象及类成员函数调用私有成员变量的限制,同理,成员函数的地址如果被外部获取(例如使用模板时),则可以突破对象,调用此...
  • 根据标准,类模板的隐式实例化只会促成static数据成员声明的实例化,不会促成其定义的实例化, 所以rc静态变量的定义没有执行,这个需要我们手动进行定义的实例化。不过这个也不难,只要手动引用一下rc,促进其定义...
  • 使用vc9.0#include "stdafx.h" #include using namespace std;template typename T>class C{public: C() { } static T m;};template typename T>T C::m;//C
  • 模板类的静态成员和普通类,普通函数的静态成员一样,我们想在函数调用后留些信息,而且这些信息随着函数调用的次数发生改变,也就说函数或者类对象执行完后,并没有完全消除而是留下了一下踪迹,比如:函数调用次数...
  • 的数组成员变量的初始化

    千次阅读 2017-10-08 14:51:20
    的数组成员变量的初始化 ...使用STL标准模板库之后,编程时已经很少使用数组和指针,相反,多使用序列容器vector代替...在的构造函数中可以使用成员初始化表初始化各个成员变量,这种方法是很受推荐和赞扬的
  • c++模板类静态成员初始化

    千次阅读 2019-07-03 10:00:11
    template<class T> class ThreadPool { private: unsigned int max_task_number; } template<class T> unsigned int ThreadPool<T>::max_task_number=0; 按照颜色对应修改就可了。......
  • 其中成员变量有静态变量和实例变量两种,的成员方法有构造方法、静态方法(含静态主方法)和一般的方法(主要有对成员变量的set和get方法,以及一些行为动作)。  是具体对象生成的一个模板
  • 这篇文章主要介绍关于模板类中如果有static变量如何初始化问题。 重要:如果不初始化static变量,那么编译可能没有问题,但是程序有问题,可能编译有问题,但是不能确定是初始化问题。 #include"iostream" ...
  • C++模板类的虚函数成员

    千次阅读 2016-11-11 10:06:26
    但是虚函数成员例外,原因应该是在定义一个模板类类型的变量时(使用模板类),为了确定虚函数表的大小,就已经实例化了虚函数成员。(个人理解,有错见谅) 有关虚函数表: 关于虚函数,其主要目的是为了实现...
  • 例如有如下,class A ...怎么声明A的成员函数指针或成员变量指针呢?int* (A::*func_ptr) (void) = &A::func; int A::*obj_ptr = &A::mem;上面声明了指向成员函数func的函数指针,和指向成员变量mem的变量指针
  • 模板类作为类成员

    千次阅读 2006-10-03 13:07:00
    对于模板类A,如果模板类B把A作为成员,则模板在定义模板B之前,只需声明模板B就可以,不必给出B的定义,只要在实例化B的之前,给出A的定义就可以了。这点很像依赖于模板的函数解析。例如:#include iostream>using...
  • 在具体编写代码时,使用了静态成员变量和静态函数。代码如下: class Camera { private: //(省略若干代码) static Camera* pCamera ; //(省略若干代码) public: //(省略若干代码) static Camera* ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 122,052
精华内容 48,820
关键字:

使用模板类做成员变量