将C .inc文件更改为.h&的.cpp

时间:2014-05-27 15:19:50

标签: c++ c

我有一个用C编写的.inc文件。它包含一些带有实现的定义和方法签名。

.inc文件:

#define CONCAT(x,y)    x ## y
#define LCONCAT(x,y)  CONCAT(x,y)

#define DLIST          LCONCAT(LCONCAT(double_,LISTELEMENT),_list)
#define DELETEDFIRST   LCONCAT(delete_first_double_,LISTELEMENT)

int DELETEDFIRST (DLIST **first, DLIST **last);

int DELETEDFIRST (DLIST **first, DLIST **last)
{...}

我想把它带到c ++。在我的.h文件中,我有define指令和方法签名(封装在命名空间中)。在.cpp中,我只有方法实现。

.h文件

#define CONCAT(x,y)    x ## y
#define LCONCAT(x,y)  CONCAT(x,y)

#define DLIST          LCONCAT(LCONCAT(double_,LISTELEMENT),_list)
#define DELETEDFIRST   LCONCAT(delete_first_double_,LISTELEMENT)

namespace ListFunctions {
int DELETEDFIRST (DLIST **first, DLIST **last);
}

.cpp文件

# include ListFunctions.h

namespace ListFunctions {
     int DELETEDFIRST (DLIST **first, DLIST **last) {...}
}

我打算在开发我的模块时使用这些列表函数。在我的module.h中,我定义了一个类型 double_ 节点 _list (双端),在我的module.cpp中,我将LISTELEMENT定义为“ node “然后包含ListFunctions.h。但ListFunctions.cpp中的相同内容会导致编译错误:

..\ListFunctions.h(86): error C2065:'double_LISTELEMENT_list' : undeclared identifier
..\ListFunctions.h(86): error C2065: 'first' : undeclared identifier 
..\ListFunctions.h(86): error C2065: 'double_LISTELEMENT_list' : undeclared identifier 
..\ListFunctions.h(86): error C2065: 'last' : undeclared identifier 
..\ListFunctions.h(86): error C2078: too many initializers

后来我想把c风格的实现翻译成c ++。由于我缺乏经验,我想知道其他人是否同意我在做什么。

2 个答案:

答案 0 :(得分:9)

停止。很明显你知道C,但你不懂C ++。 在尝试使用它编写代码之前学习C ++。这是一种与C语言明显不同的语言,并且尝试编写C ++就好像它是“C with stuff”一样会导致代码错误。

首先:你想要的几乎肯定是带有方法的C ++ class,而不是包含对数据类型(可能是结构?)进行操作的函数的命名空间。

第二:我不确定你在这里定义的所有宏到底是做什么的,但它看起来好像你试图定义一组变量函数。这个概念已经作为模板存在于C ++中。不要试图用宏复制它;你会混淆那些阅读你代码的人。

答案 1 :(得分:2)

对于特定的问题,C和C ++都无效,两者都应该调用该错误。解决方案是将这一行放在函数之前,告诉编译器稍后将定义此结构,但是现在我们需要指针或引用它。

struct DLIST;

但是,您遇到的主要问题是您的目标似乎是将函数定义放在cpp文件中。不幸的是,在C和C ++中不能以通用方式干净地完成。问题是您希望能够为各种类型(通过模板或宏)专门化List,但是当您编译该cpp文件本身时,它无法知道要为列表专门化的类型。对于C和C ++中的通用结构,通常定义仍然必须在某种标题或包含文件中。

有一种替代方案,可以让你将函数定义放入cpp文件中,但它非常奇怪,我不推荐它:

list_declarations.hpp

template<class LISTELEMENT>
class double_list {
    typedef LISTELEMENT value_type;
    struct iterator {
       ...iterator stuff
    };
    static int DELETEDFIRST (iterator first, iterator last);
};
extern template class double_list<int>; //declare int specialization
extern template class double_list<char>; //declare char specialization

list_definitions.cpp:

#include "list_declarations.h"

template<class LISTELEMENT>
int double_list<LISTELEMENT>::DELETEDFIRST(
    double_list<LISTELEMENT>::iterator first, 
    double_list<LISTELEMENT>::iterator last)
{
    ...implementation
}

template class double_list<int>; //define int specialization
template class double_list<char>; //define char specialization
//note that all of these _must_ be in the same file as the function definitions

在C ++中制作通用列表的常规方法是模糊的:

#pragma once

template<class LISTELEMENT, class allocator=std::allocator<LISTELEMENT>>
class double_list {
public:
    typedef allocator allocator_type;
    typedef typename allocator::value_type value_type;
    typedef typename allocator::reference reference;
    typedef typename allocator::const_reference const_reference;
    typedef typename allocator::difference_type difference_type;
    typedef typename allocator::size_type size_type;

    class iterator {
        DLIST * current;           
        explicit iterator(DLIST* c);
    public:
        typedef LISTELEMENT value_type;
        typedef LISTELEMENT& reference;
        typedef LISTELEMENT* pointer;
        typedef std::ptrdif_t difference_type;
        typedef std::bidirectional_iterator_tag iterator_category;
        iterator();
        iterator& operator++(); //prefix increment
        iterator operator++(int); //postfix increment
        iterator& operator--(); //prefix decrement
        iterator operator--(int); //postfix decrement
        reference operator*() const;
        pointer operator->() const;
        friend bool operator==(const iterator&, const iterator&);
        friend bool operator!=(const iterator&, const iterator&); 
        friend void swap(iterator& lhs, iterator& rhs);
    };
    class const_iterator { 
        const DLIST * current;           
        explicit iterator(const DLIST* c);
    public:
        const_iterator(iterator c);
        ...see above
    };

    double_list();
    double_list(const double_list& rhs);
    ~double_list();
    double_list& operator=(const double_list& rhs);

    int delete_first(iterator first, iterator last);
private:
    pointer first;
    pointer last;
};

加上Writing your own STL Container中感兴趣的任何其他成员。由于它是模板类,因此所有函数定义都必须位于标题中。显然,这与非常不相同。