You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++调用匿名命名空间函数报错:undefined reference问题求助

问题描述

我是计算机科学初学者,正在完成作业,当前学习内存分配、头文件使用及动态内存分配。作业要求在头文件中使用匿名命名空间定义const变量和函数声明,但编译时第28行出现"undefined reference to anonymous namespace"错误,不知如何修复,附上相关代码:

mylibrary.hpp

#include <iostream>
#include <memory>

#ifndef MYLIBRARY_HPP
#define MYLIBRARY_HPP

namespace
{
    int counter = 0;
    const int SIZE = 10;
    std::unique_ptr<char[]> deleteRepeats(char arr[]);
}

#endif // MYLIBRARY_HPP

main.cpp

using std::cin;
using std::cout; //using declarations to avoid namespace std
using std::endl;

int main()
{
   
    char originalArray[SIZE]; //declaration of array that will be used in the program and all its values
    originalArray [0] = 'a';
    originalArray [1] = 'b';
    originalArray [2] = 'b';
    originalArray [3] = 'c';
    originalArray [4] = 'a';
    originalArray [5] = 'c';
    originalArray [6] = 'a';
    originalArray [7] = 'c';
    originalArray [8] = 'b';
    originalArray [9] = 'c';
    std::unique_ptr<char[]> noRepeats = deleteRepeats(originalArray); //function call

    cout << "the amount of repeats is... " << SIZE-counter << endl; //prints out the number of repeats

    for(int i =0; i<counter; i++) //displays new array
    {
        cout << noRepeats[i] << endl;
    }

    return 0;
}

function.cpp

#include <iostream>
#include <memory>

//my function definitions
namespace
{
    //Precondition: an array of defined size contains only valid characters
    //Postconition: a new array is generated with only unique values
    std::unique_ptr<char[]> deleteRepeats(char arr[]) //goes through the array and checks if it has repeats
    {
        for(int i=0; i<SIZE/2; i++)
        {
            if(arr[i] = arr[SIZE -1-i]) //marks any repeats
            {
                arr[i] = '-';
                arr[SIZE-1-i] = '-';
            }
        }
        for(int i =0; i<SIZE; i++) //counts new array
        {
            if(arr[i] != '-')
            {
                counter++;
            }
        }
        std::unique_ptr<char[]> newArray(new char[counter]); //declares a new array using a pointer
        int location = 0;
        for(int i = 0; i<SIZE; i++)
        {
            if(arr[i] != '-')
            {
                newArray[location++] = arr[i];
            }
        }
        return newArray;
    }
}

错误原因与修复方案

核心问题:匿名命名空间的作用域限制

C++中,匿名命名空间的成员仅在当前编译单元(单个.cpp文件)内可见。你的写法会导致:

  1. 头文件的匿名命名空间被main.cpp和function.cpp分别包含,两个编译单元会生成完全独立的counter、SIZE和deleteRepeats声明实例。
  2. main.cpp调用的deleteRepeats是自身编译单元内的声明,但该函数没有定义(定义在function.cpp的匿名命名空间里,属于另一个独立实例),因此链接阶段出现未定义引用错误。

修复步骤

1. 调整头文件,移除匿名命名空间

将需要跨编译单元共享的内容移出匿名命名空间,用extern声明共享变量和函数:

修改mylibrary.hpp:

#include <iostream>
#include <memory>

#ifndef MYLIBRARY_HPP
#define MYLIBRARY_HPP

// 声明共享常量,用extern让其他编译单元可见
extern const int SIZE;
// 声明共享函数
std::unique_ptr<char[]> deleteRepeats(char arr[]);
// 声明全局计数器变量
extern int counter;

#endif // MYLIBRARY_HPP

2. 在function.cpp中定义变量与函数

将原匿名命名空间内的内容移到全局作用域,同时包含头文件:

修改function.cpp:

#include <iostream>
#include <memory>
#include "mylibrary.hpp"

// 定义常量与全局变量
const int SIZE = 10;
int counter = 0;

// 函数定义
std::unique_ptr<char[]> deleteRepeats(char arr[])
{
    for(int i=0; i<SIZE/2; i++)
    {
        // 注意:原代码是赋值操作=,改为比较操作==
        if(arr[i] == arr[SIZE -1-i])
        {
            arr[i] = '-';
            arr[SIZE-1-i] = '-';
        }
    }
    counter = 0; // 每次调用前重置计数器,避免累计错误
    for(int i =0; i<SIZE; i++)
    {
        if(arr[i] != '-')
        {
            counter++;
        }
    }
    std::unique_ptr<char[]> newArray(new char[counter]);
    int location = 0;
    for(int i = 0; i<SIZE; i++)
    {
        if(arr[i] != '-')
        {
            newArray[location++] = arr[i];
        }
    }
    return newArray;
}

3. 修改main.cpp,添加头文件包含

修改main.cpp开头,引入头文件:

#include "mylibrary.hpp"
using std::cin;
using std::cout;
using std::endl;

// 剩余main函数代码不变...

额外注意事项

  • 原代码中if(arr[i] = arr[SIZE -1-i])是赋值操作,会导致逻辑错误,必须改为比较运算符==。
  • 全局变量counter需要在每次调用deleteRepeats前重置,否则多次调用会累计数值。
  • 如果作业强制要求使用匿名命名空间,只能将函数定义和声明合并到同一个编译单元(比如把function.cpp内容合并到main.cpp),但这种写法不符合代码分离的规范,更合理的替代方案是使用具名命名空间。

内容的提问来源于stack exchange,提问作者unit5016

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 07:35:44