Изменение файла C .inc на .h & .cpp

0

У меня есть файл.inc, написанный на C. Это содержит некоторые определения и сигнатуры методов с их реализациями.

.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) {...}
}

Я планирую использовать эти функции списка в разработке моего модуля. В моем модуле.h я определяю тип double_node_list (с двойным концом), а в моем module.cpp я определяю LISTELEMENT как " узел ", а затем включаю 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++. Поскольку мне не хватает опыта, я хочу знать, согласны ли другие с тем, что я делаю.

  • 1
    Это поможет нам, если вы сможете опубликовать ошибки. Убедитесь, что вы .h свой .h файл от нескольких включений, см. Здесь или здесь .
  • 0
    Ошибки: .. \ ListFunctions.h (86): ошибка C2065: 'double_LISTELEMENT_list': необъявленный идентификатор ... \ ListFunctions.h (86): ошибка C2065: 'first': необъявленный идентификатор ... \ ListFunctions.h (86 ): ошибка C2065: 'double_LISTELEMENT_list': необъявленный идентификатор ... \ ListFunctions.h (86): ошибка C2065: 'последняя': необъявленный идентификатор ... \ ListFunctions.h (86): ошибка C2078: слишком много инициализаторов
Показать ещё 1 комментарий
Теги:

2 ответа

9

Стоп. Очевидно, что вы знаете C, но вы не знаете C++. Изучите C++, прежде чем пытаться писать код, используя его. Это значительно отличный язык от C, и попытка написать C++, как будто это "C с вещами" приведет к плохому коду.

Во- первых: То, что вы хотите здесь почти наверняка C++ class с методами, а не пространство имен, содержащее функции, которые работают на типе данных (возможно, структуры?).

Во-вторых: я не уверен, что именно все макросы, которые вы здесь определили, делают, но похоже, что вы пытаетесь определить набор вариантов. Эта концепция уже существует в C++, как шаблоны. Не пытайтесь копировать его с помощью макросов; вы просто смутите любого, кто читает ваш код.

  • 0
    Ну, у меня есть одинарные и двусторонние списки. В CI определили добавление, добавление, удаление и т.д. в обоих этих списках с помощью макросов.
  • 0
    Хотя эти макросы, возможно, хороши (если немного странны) в C, они абсолютно не подходят для решения проблемы в C ++. Выучите язык полностью, прежде чем продолжить.
Показать ещё 1 комментарий
2

Что касается вашей конкретной проблемы, то и C, и C++ являются недопустимыми, и оба должны вызывать эту ошибку. Решение состоит в том, чтобы поставить эту строку перед функциями, которая сообщает компилятору, что позже эта структура будет определена, но сейчас нам понадобятся указатели или ссылки на нее.

struct DLIST;

Однако основная проблема, с которой вы сталкиваетесь, заключается в том, что ваша цель состоит в том, чтобы поместить определения функций в файл cpp. К сожалению, это невозможно сделать чисто C и CN10. Проблема заключается в том, что вы хотите иметь возможность специализироваться на 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;
};

Кроме того, любые другие заинтересованные лица в написании вашего собственного контейнера STL. Поскольку это класс шаблона, все определения функций должны быть в заголовке. Очевидно, это заметно отличается от пути C.

  • 0
    Вы правы в своих предположениях. У меня есть два типа списка, для которого я хочу отделить реализации. Один из них однократно связан, а другой - дважды. Что вы порекомендуете?
  • 0
    @AvishekDutta: Честно? Просто используйте std::vector .
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню