Ошибка конструктора DFA, что делать для действительного объявления?

Я должен записать этот проект, в котором я должен сделать DFA. Мне трудно понять, как именно написать мой конструктор, чтобы не получить следующую ошибку no matching function for call to 'DFA::DFA(int&, char [2], char [4][2], char&, char [1])'| . Любая помощь приветствуется. Вот код:


#include <iostream>
#include<cstring>
using namespace std;
class DFA
{
    int number_of_states;
    char* alphabet;
    char** transition_table;
    char start_state;
    char* final_states;
    public:
        DFA(int,char*,char**,char,char*);
};
DFA::DFA(int snumber_of_states,char* salphabet,char** stransition_table,char    sstart_state, char* sfinal_states)
{
    number_of_states= snumber_of_states;
    int l1=strlen(salphabet);
    alphabet=new char[l1+1];
    for(int i=0;i<l1+1;i++)
    {
        alphabet[i]=salphabet[i];
    }

    transition_table=new char* [number_of_states];
    for(int h=0;h<number_of_states;++h)
    {
        transition_table[h]=new char[l1+1];
    }
    for(int j=0;j<number_of_states;j++)
    {
        for(int k=0;k<l1+1;k++)
            transition_table[j][k]=stransition_table[j][k];
    }

    start_state=sstart_state;

    int l2=strlen(sfinal_states);
    final_states=new char [l2+1];
    for(int r=0;r<l2+1;r++)
    {
        final_states[r]=sfinal_states[r];
    }
}


int main()
{
    char start_state='0';
    char final_states[1]={'3'};
    int number_of_states=4;
    char alphabet[2]={'a','b'};
    char transition_table[4][2]={
                        {'1','1'},
                        {'2','1'},
                        {'0','3'},
                        {'3','-'}
                        };

    DFA automaton(number_of_states,alphabet,transition_table,start_state,final_states);
}

person user3658099    schedule 20.05.2014    source источник
comment
Код, который у вас сейчас есть, практически полностью написан на C и очень мало на C++. Я настоятельно рекомендую вам использовать std::string вместо char* и std::vector<std::string> вместо char** или new char[]. В противном случае у вас, скорее всего, возникнут другие проблемы (связанные с памятью), которые будет гораздо сложнее понять, чем вызов конструктора.   -  person PaulMcKenzie    schedule 20.05.2014


Ответы (2)


Ошибка no matching function for call to 'DFA::DFA(int&, char [2], char [4][2], char&, char [1]) связана с тем, что настоящий двумерный массив (в данном случае char[4][2]) не совпадает с char**. Это простое объяснение (я не буду объяснять, почему это не одно и то же, но в этом и проблема).

Кроме того, не пытайтесь привести свой массив к char**, чтобы "закрыть компилятор" - это будет катастрофой. В вашем коде также есть утечки памяти из-за использования new[] без какого-либо вызова delete[].

Вот решение на C++, которое избавляет вас от использования такого количества C-измов в вашем коде:

#include <iostream>
#include <string>
#include <vector>

typedef std::vector<std::string> StringArray;

class DFA
{
    int number_of_states;
    std::string alphabet;
    StringArray transition_table;
    char start_state;
    std::string final_states;

public:
    DFA(int, const std::string&, const StringArray&, char, const std::string&);
};

DFA::DFA(int snumber_of_states, const std::string& salphabet, 
         const StringArray& stransition_table, char sstart_state, 
         const std::string& sfinal_states) :
            number_of_states(snumber_of_states), 
            alphabet(salphabet),
            start_state(sstart_state),
            transition_table(stransition_table),
            final_states(sfinal_states) { }

int main()
{
    char start_state='0';
    std::string final_states = "3";
    int number_of_states=4;
    std::string alphabet = "ab";
    StringArray transition_table;
    transition_table.push_back("11");
    transition_table.push_back("21");
    transition_table.push_back("03");
    transition_table.push_back("3-");
    DFA automaton(number_of_states, alphabet, transition_table, start_state,
                  final_states);
}

Обратите внимание на использование std::vector и std::string. Приведенный выше код — это в основном то, что делал весь ваш код, используя new[] и delete[]. Код краток -- нет вызовов strlen, нет циклов, нет утечек памяти, и все инициализируется корректно (обратите внимание на member initialization list в конструкторе DFA).

Если вы начали с этого, вы, скорее всего, продолжите писать программу для решения вашей реальной цели, а именно написать DFA, а не бороться с указателями на символы и динамически выделяемой памятью.

Изменить: вот программа main(), но с использованием синтаксиса uniform initialization С++ 11:

int main()
{
    char start_state='0';
    std::string final_states = "3";
    int number_of_states=4;
    std::string alphabet = "ab";
    StringArray transition_table = {"11", "21", "03", "3-"};
    DFA automaton(number_of_states, alphabet, transition_table, start_state, 
                  final_states);
}

Так что теперь код стал еще короче, чем в первой версии.

person PaulMcKenzie    schedule 20.05.2014
comment
Из любопытства, почему вы не использовали юниформ-инициализацию для StringArray? - person soandos; 21.05.2014
comment
@soandos - я мог бы, но хотел, чтобы решение работало для компиляторов до C++ 11. - person PaulMcKenzie; 21.05.2014
comment
Обновлен ответ, чтобы добавить initialization syntax версию. - person PaulMcKenzie; 21.05.2014

Проблема здесь в вашем третьем параметре, который не имеет нужного типа.

Цитата из сообщения об ошибке от компилятора (gcc 4.9):

prog.cpp:14:1: примечание: неизвестно преобразование аргумента 3 из 'char [4][2]' в 'char**' prog.cpp:4:7: примечание: constexpr DFA::DFA(const DFA& )

Чтобы решить проблему, которая у вас есть, просто измените строки так:

DFA(int,char*,char[4][2],char,char*);

и

DFA::DFA(int snumber_of_states,char* salphabet, char stransition_table[4][2],char sstart_state, char* sfinal_states)

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

person soandos    schedule 20.05.2014