美文网首页
使用模板会不会重复定义?

使用模板会不会重复定义?

作者: leon0514 | 来源:发表于2024-07-08 17:24 被阅读0次

不使用模板

//  add.hpp
/*
 **********************************************************
 * Create time :  2024-07-09 16:17:02
 * Author      :  leon
 * Email       :  leon@^-^
 * Filename    :  add.hpp
 * Description :  
 **********************************************************
 */

#ifndef __ADD_HPP 
#define __ADD_HPP 

int add(int x, int y)
{
    return x + y;
}

#endif  // __ADD_HPP

// test1.cpp
/*
 **********************************************************
 * Create time :  2024-07-09 16:20:21
 * Author      :  leon
 * Email       :  leon@^-^
 * Filename    :  test1.cpp
 * Description :  
 **********************************************************
 */

#include "add.hpp"
#include <iostream>

void test1(int x, int y)
{
    int result = add(x, y);
    std::cout << "test1 add : " << result << std::endl;
}

// test2.cpp
/*
 **********************************************************
 * Create time :  2024-07-09 16:20:13
 * Author      :  leon
 * Email       :  leon@^-^
 * Filename    :  test.cpp
 * Description :  
 **********************************************************
 */


#include "add.hpp"
#include <iostream>

void test2(int x, int y)
{
    int result = add(x, y);
    std::cout << "test2 add : " << result << std::endl;
}

// main.cpp
#include "add.hpp"
#include <iostream>

void test1(int x, int y);
void test2(int x, int y);

int main()
{
    int x = 100;
    int y = 200;
    int r = add(x, y);
    std::cout << "main add : " << r << std::endl;
    test1(x, y);
    test2(x, y);
    return 0;
}

编译结果
没有使用模板,在头文件中定义,会出现重复定义的结果,无法通过编译

image.png

使用模板

在链接阶段之前,模板没有进行实例化,因此也没有地址,在链接的时候,调用模板的地方无法通过名字在别的文件中找到模板的地址,也就无法实现模板的分离编译。
所以只能在头文件或者cpp文件中定义和实现。如果在cpp文件中定义和实现,无法在其他文件中也用到定义的函数或者类。现在测试在头文件中实现会不会出现重复定义。

/*
 **********************************************************
 * Create time :  2024-07-09 16:17:02
 * Author      :  leon
 * Email       :  leon@^-^
 * Filename    :  add.hpp
 * Description :  
 **********************************************************
 */

#ifndef __ADD_HPP 
#define __ADD_HPP 

template<typename T>
T add(T x, T y)
{
    return x + y;
}

#endif  // __ADD_HPP

int add(int x, int y)
{
    return x + y;
}

#endif  // __ADD_HPP

// test1.cpp
/*
 **********************************************************
 * Create time :  2024-07-09 16:20:21
 * Author      :  leon
 * Email       :  leon@^-^
 * Filename    :  test1.cpp
 * Description :  
 **********************************************************
 */

#include "add.hpp"
#include <iostream>

void test1(int x, int y)
{
    int result = add(x, y);
    std::cout << "test1 add : " << result << std::endl;
}

// test2.cpp
/*
 **********************************************************
 * Create time :  2024-07-09 16:20:13
 * Author      :  leon
 * Email       :  leon@^-^
 * Filename    :  test.cpp
 * Description :  
 **********************************************************
 */


#include "add.hpp"
#include <iostream>

void test2(int x, int y)
{
    int result = add(x, y);
    std::cout << "test2 add : " << result << std::endl;
}

// main.cpp
#include "add.hpp"
#include <iostream>

void test1(int x, int y);
void test2(int x, int y);

int main()
{
    int x = 100;
    int y = 200;
    int r = add(x, y);
    std::cout << "main add : " << r << std::endl;
    test1(x, y);
    test2(x, y);
    return 0;
}

编译结果

image.png

原理

模板的特性

模板实例化:模板是一种编译时机制,只有在实际使用时才会实例化。当一个模板在头文件中定义和实现时,它并不会立即生成代码,只有在某个源文件中使用该模板并给定具体类型时,编译器才会生成相应的代码。

一次性实例化:每个模板实例(即每个具体类型的模板)在整个程序中只实例化一次。即使模板的定义和实现被包含在多个源文件中,编译器也会确保每个具体类型的模板实例只生成一次代码。

链接器的处理

内联机制:C++ 编译器通常会将模板函数视为内联函数处理。这样,在多个源文件中包含同一个头文件时,编译器会在每个包含的源文件中生成内联代码,但链接器会确保只保留一个最终实例。

外部链接:模板代码的具体实现是在头文件中提供的,但这些代码并不会在头文件中立即生成二进制代码,而是在使用时才生成。在链接阶段,链接器会处理这些实例化的代码,并去除重复的部分。

相关文章

  • 小程序中模板的使用

    使用模板可以减少重复代码的使用,使用方法如下 1.使用方法 2.使用方法 在单独的文件中定义好模板通过import...

  • 微信小程序定义模板template

    小程序中提供了模板功能,我们可以自定义一些模板,将一些多次重复使用的布局和样式定义成模板,比如商品列表之类的 步骤...

  • 小程序template使用

    定义模板使用 name 属性,作为模板的名字。然后在