zoukankan      html  css  js  c++  java
  • C++/CLI中class成员声明与实现分开在不同文件时必须添加namespace

    以下是我的代码:

    //TaskConfigFile.h
    #pragma once
    using namespace System::Collections::Generic;
    using namespace System;
    using namespace System::IO;
    using namespace System::Text;
    
    ref class TaskConfigFile
    {
    public:
        TaskConfigFile();
        TaskConfigFile(String^ str_link, Int64 file_size, short threads_sum);
        TaskConfigFile(String^ str_link, Int64 file_size);
    
        String^ link;//下载链接
        String^ fileName;//文件名
        String^ filePath;//文件存储路径
        Int64 fileSize;//文件总大小
        Int64 blockSize;//文件分块大小
        Int64 sumDownloadedSize;//已下载的总大小
        short threadsSum;//线程总数,默认为5
    
        //以字典记录各分块已下载的大小,key为分块的起始位置(字节),value为此分块已下载的大小
        Dictionary<Int64, Int64>^ blockDownloadedSize;
    
    #ifdef DEBUG
        Debug::Listeners->Add( gcnew TextWriterTraceListener( Console::Out ) );
        Debug::AutoFlush = true;
    #endif
        bool Save();//保存配置信息
        bool Load(String^ path);//加载配置信息
    };
    //TaskConfigFile.cpp
    #include "stdafx.h"
    #include "TaskConfigFile.h"
    
    TaskConfigFile::TaskConfigFile():
        link(nullptr), fileName(nullptr), fileSize(0L), filePath(nullptr), blockSize(0L), sumDownloadedSize(0L), threadsSum(5)
    {
        blockDownloadedSize = gcnew Dictionary<Int64, Int64>(threadsSum);
    }
    
    TaskConfigFile::TaskConfigFile(String^ str_link, Int64 file_size, short threads_sum):
        link(str_link), fileSize(file_size), threadsSum(threads_sum), sumDownloadedSize(0)
    {
        blockDownloadedSize = gcnew Dictionary<Int64, Int64>(threadsSum);
    }
    
    TaskConfigFile::TaskConfigFile(String^ str_link, Int64 file_size):
        link(str_link), fileSize(file_size), threadsSum(5), sumDownloadedSize(0)
    {
        blockDownloadedSize = gcnew Dictionary<Int64, Int64>(threadsSum);
    }
    
    bool TaskConfigFile::Save()
    {
        String^ path = String::Concat(filePath, fileName, ".tmp");
        Stream^ writeStream = gcnew FileStream(path, FileMode::Create, FileAccess::Write);
        if(writeStream == nullptr)
        {
    #ifdef DEBUG
            Diagnostics::Debug::WriteLine("文件路径错误!");
    #endif
            return false;
        }
    
        BinaryWriter^ binaryWriter = gcnew BinaryWriter(writeStream, Encoding::ASCII);
        binaryWriter->Write(this->link);
        binaryWriter->Write(this->fileName);
        binaryWriter->Write(this->filePath);
        binaryWriter->Write(this->fileSize);
        binaryWriter->Write(this->blockSize);
        binaryWriter->Write(this->sumDownloadedSize);
        binaryWriter->Write(this->threadsSum);
        for each(KeyValuePair<Int64, Int64> pair in blockDownloadedSize)
        {
            binaryWriter->Write(pair.Key);
            binaryWriter->Write(pair.Value);
        }
        writeStream->Close();
        binaryWriter->Close();
        return true;
    }
    
    bool TaskConfigFile::Load(String^ path)
    {
        Stream^ readStream = gcnew FileStream(path, FileMode::Open, FileAccess::Read);
        if(readStream == nullptr)
        {
    #ifdef DEBUG
            Diagnostics::Debug::Indent();
            Diagnostics::Debug::WriteLine("error: 打开文件失败!");
            Diagnostics::Debug::WriteLine("Paht: {0}", path);
            Diagnostics::Debug::UnIndent();
    #endif
            return false;
        }
        BinaryReader^ binaryReader = gcnew BinaryReader(readStream);
        try
        {
            link = binaryReader->ReadString();
            fileName = binaryReader->ReadString();
            filePath = binaryReader->ReadString();
            fileSize = binaryReader->ReadInt64();
            blockSize = binaryReader->ReadInt64();
            sumDownloadedSize = binaryReader->ReadInt64();
            threadsSum = binaryReader->ReadInt16();
            for(int i = 0; i < threadsSum; ++i)
            {
                Int64 key = binaryReader->ReadInt64();
                Int64 value = binaryReader->ReadInt64();
                blockDownloadedSize->Add(key, value);
            }
        }
        catch(EndOfStreamException^ ex)
        {
    #ifdef DEBUG
            Diagnostics::Debug::Indent();
            Diagnostics::Debug::WriteLine("The end of the stream is reached."); 
            Diagnostics::Debug::WriteLine(ex->Message);
            Diagnostics::Debug::Unindent();
    #endif
            readStream->Close();
            binaryReader->Close();
            return true;
        }
    
        return true;
        
    }

    我将他们放在同一个文件就能编译通过。一旦分开就会出现链接错误:

    这是因为.NET以程序集作为编译单元,每一个程序集里类的成员声明与定义必须在同一个namespace下,而这两个文件中并没有声明namespace,所以链接器找不到TaskConfigFile Class成员的实现代码。

    必须将它们声明在同一个namspace中:

    //TaskConfigFile.h
    namespace xxx
    {
        //..............      
    }
    
    
    //TaskConfigFile.cpp
    using namespace xxx;
  • 相关阅读:
    基础数据类型补充
    编码转换
    is 和 == 的区别
    字典 dict
    列表与元组
    python基础第一节
    poll函数
    基本 TCP 的回射服务器
    文件IO
    base | AtomicIntegerT类
  • 原文地址:https://www.cnblogs.com/dvwei/p/3384668.html
Copyright © 2011-2022 走看看