| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3969 人关注过本帖, 1 人收藏
标题:模板函数/模板类实例化问题
取消只看楼主 加入收藏
韩海0312
Rank: 1
等 级:新手上路
帖 子:27
专家分:0
注 册:2012-8-11
结帖率:83.33%
收藏(1)
已结贴  问题点数:20 回复次数:8 
模板函数/模板类实例化问题
问题描述
对下面每条带标签的语句,解释发生了什么实例化(如果有的话),如果一个模板被实例化,解释为什么,
如果一个模板没有被实例化,解释为什么没有。

代码如下
程序代码:
template <typename T> class Stack { };

void f1(Stack<char>);                   // (a)

class Exercise {
    Stack<double> &rsd;                 // (b)
    Stack<int>    si;                   // (c)
};

int main() {
    Stack<char> *sc;                    // (d)
    f1(*sc);                            // (e)
    int iObj = sizeof(Stack< string >); // (f)
}
是不是这样的
1. a, b和d没有实例化。
2. c, f只实例化了类, 没有实例化任何类成员
3. e, 实例化了Stack<char> 同时实例化了copy 构造函数

上面的答案经过测试得出的结论,
但是不知道原理是怎样的?
难道是依据是否分配内存为准? 如果是这样的话,c 和 f也没分配内存啊

求指教?


[此贴子已经被作者于2017-6-12 17:25编辑过]

搜索更多相关主题的帖子: color 标签 
2017-06-12 16:27
韩海0312
Rank: 1
等 级:新手上路
帖 子:27
专家分:0
注 册:2012-8-11
收藏
得分:0 
回复 2楼 l291920497
我也是小菜,共同学习

分享下,我这这类问题的想法
我将上面的代码在加一个func的定义结果有些变化

程序代码:
template <typename T> class Stack { };

void f1(Stack<char>);                   // (a)

class Exercise {
    Stack<double> &rsd;                 // (b)
    Stack<int>    si;                   // (c)
};

void f1(Stack<char> g)                   // (g)
{
}

int main() {
    Stack<char> *sc;                    // (d)
    f1(*sc);                            // (e)
    int iObj = sizeof(Stack< string >); // (f)
}

(g)实例化,但未实例化任何成员
(g) 和 (a)的区别是一个是声明,一个是定义,(定义在调用时是要分配内存的)
是否实例化的关键是看是否将要分配该类型的对象内存(强调“将要”是因为函数定义时,型参其实没有分配内存,是在调用时定义的)
另外你说sizeof结果为一个字节的问题,原因在于我们的类没有数据成员(定义的非虚成员函数,不占实例的内存,它们只属于类型(不知道怎么表达对不对))
sizeof本来应该是0,但是类的对象实例一定是要占用一定内存的,否在无法使用这些对象,至于占用多大,要看使用的编译器

上面的a~g 应该是这样的

(a) 声明,不分配内存,不实例化
(b) 和 (d) 类是引用和指针不需要实例化
(c) 需要实例化,将会分配内存
(e) 实例化copy constructor
(f) 实例化
2017-06-14 19:23
韩海0312
Rank: 1
等 级:新手上路
帖 子:27
专家分:0
注 册:2012-8-11
收藏
得分:0 
回复 3楼 韩海0312
你可以测试上面的结果,我已经测试过,解释不一定对,仅供参考
2017-06-14 19:25
韩海0312
Rank: 1
等 级:新手上路
帖 子:27
专家分:0
注 册:2012-8-11
收藏
得分:0 
回复 5楼 rjsp
你是说,使用显示实例化要使用的版本,避免这一类问题的发生么?
2017-06-15 09:37
韩海0312
Rank: 1
等 级:新手上路
帖 子:27
专家分:0
注 册:2012-8-11
收藏
得分:0 
回复 7楼 rjsp
那你的说法,
(a) void f1(Stack<char>);
(b) Stack<double> &rsd;
(d) Stack<char> *sc;
这些该怎么解释呢, 这些用具体的实参替换形参, 但是这些没有实例化
2017-06-15 19:53
韩海0312
Rank: 1
等 级:新手上路
帖 子:27
专家分:0
注 册:2012-8-11
收藏
得分:0 
回复 9楼 rjsp
你说的挺好, 我很赞同, 可是模板是什么时候实例化的呢,
这个才是我们一直关注的问题,我问题中描述中例子,他们遵循一个什么样的规则实例化,
我想知道这个
2017-06-16 14:35
韩海0312
Rank: 1
等 级:新手上路
帖 子:27
专家分:0
注 册:2012-8-11
收藏
得分:0 
回复 10楼 韩海0312
我的模板instantiation, 就是指什么时候通过“规则”实例化出对应的类或者函数,

但是我不懂的是如
(a) void f1(Stack<char>); //这里为什么没有实例化出类Stack<char>
(b) Stack<double> &rsd;   //如果实例化模板,b和d 为什么不需要实例化出模板
(d) Stack<char> *sc;
在我觉得,模板是实例化一种类型或者函数的规则,
例如定义一种类型, 如(a) 这时候为什么不需要类型的(Stack<char>)完整定义,
在比如为什么(b) 和(d) 不要实例化出对应的类型,
我看到的一个解释是这样的:
notice the pointer/reference stuff: they don't require instantiation since no data is actually allocated(a pointer
is just a few bytes to contain the address, has no need to have all the data stored.. take a look at the pimpl idiom ).
Only when stuff is allocated then the template has to be completely resolved (and that happens at compile-time, that's why they usually need both declaration and definition.. there's no linking phase yet)
这种解释其实在说,例如指针32位机中都是4字节,不需要了解类型到底是真么样子的,只有在实例化类对象的时候踩需要实例化模板类,
这怎么又把类对象和模板类的实例化搞在一起,很是费解

抛开显示话声明和定义不讲,模板只有在使用时才实例化,这个“使用该怎么解释”?
2017-06-16 16:44
韩海0312
Rank: 1
等 级:新手上路
帖 子:27
专家分:0
注 册:2012-8-11
收藏
得分:0 
回复 11楼 rjsp
是不是我说道哪里不对啊
2017-06-19 10:26
韩海0312
Rank: 1
等 级:新手上路
帖 子:27
专家分:0
注 册:2012-8-11
收藏
得分:0 
回复 11楼 rjsp
我好像理解了这个问题,不知道我感觉是对的,你可你帮我分析一下我的理解么

我的理解是这样的:
1.其实模板的实例化是个编译链接问题
假如不考虑模板,我们写几个.cpp (a.cpp, b.cpp)文件,假如a.cpp 文件中使用了b.cpp文件里的类型
使用的时候不需要考虑是b.cpp中是否有定义,只要a.cpp中有b.cpp的类型声明就可以。
那现在呢,考虑模板
模板不是类或者函数,其实就是一个规范,或者说明(用来描述如何生成类或者函数),所以在使用模板时,还有一个生成
模板对应类型的问题, 什么时候生成模板对用的类型或者函数,
1. 比如指针sc,它其实与类型无关,只与cpu寻址范围有关,所以不需要生成类型  //(d) Stack<char> *sc;
2. 引用呢,只是一个别名,生成类型是被引用一方(rsd)的事情, //Stack<double> &rsd
3. 再说函数声明中型参使用的模板,这个函数的声明这是表明在本文见中可以使用f1, 模板的实例化其实在f1的定义的时候 //(a) void f1(Stack<char>);
2017-06-19 11:43
快速回复:模板函数/模板类实例化问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.022250 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved