«В файле включено с ошибкой» с вектором - PullRequest
0 голосов
/ 30 ноября 2018

Я пытаюсь создать агрегатный класс, Pile, который использует вектор карт в качестве своих данных.

Я пытался выяснить, что происходит с этой ошибкой в ​​течение последних 3 часов, ия в тупике.Вот ошибка:

In file included from /usr/include/c++/5/vector:62:0,
                 from Pile.h:16,
                 from Pile.cpp:15:
/usr/include/c++/5/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = Card; _Args = {}]’:
/usr/include/c++/5/bits/stl_uninitialized.h:519:18:   required from ‘static _ForwardIterator std::__uninitialized_default_n_1<_TrivialValueType>::__uninit_default_n(_ForwardIterator, _Size) [with _ForwardIterator = Card*; _Size = long unsigned int; bool _TrivialValueType = false]’
/usr/include/c++/5/bits/stl_uninitialized.h:575:20:   required from ‘_ForwardIterator std::__uninitialized_default_n(_ForwardIterator, _Size) [with _ForwardIterator = Card*; _Size = long unsigned int]’
/usr/include/c++/5/bits/stl_uninitialized.h:637:44:   required from ‘_ForwardIterator std::__uninitialized_default_n_a(_ForwardIterator, _Size, std::allocator<_Tp>&) [with _ForwardIterator = Card*; _Size = long unsigned int; _Tp = Card]’
/usr/include/c++/5/bits/stl_vector.h:1311:36:   required from ‘void std::vector<_Tp, _Alloc>::_M_default_initialize(std::vector<_Tp, _Alloc>::size_type) [with _Tp = Card; _Alloc = std::allocator<Card>; std::vector<_Tp, _Alloc>::size_type = long unsigned int]’
/usr/include/c++/5/bits/stl_vector.h:279:30:   required from ‘std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const allocator_type&) [with _Tp = Card; _Alloc = std::allocator<Card>; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<Card>]’
<span class="error_line" onclick="ide.gotoLine('Pile.cpp',27)">Pile.cpp:27:23</span>:   required from here
/usr/include/c++/5/bits/stl_construct.h:75:7: error: no matching function for call to ‘Card::Card()’
     { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
       ^
In file included from Pile.h:17:0,
                 from Pile.cpp:15:
card.h:30:5: note: candidate: Card::Card(const Card&)
     Card(const Card& old);     //copy constructor
     ^
card.h:30:5: note:   candidate expects 1 argument, 0 provided
card.h:29:5: note: candidate: Card::Card(int, char)
     Card(int r, char s); //parameterized constructor
     ^
card.h:29:5: note:   candidate expects 2 arguments, 0 provided

Call Stack
#   Function    File:Line
Local Variables
Variable    Value
Display Expressions
Expression  Value   
Breakpoints and Watchpoints
    #   Description 

Я чувствую, что я так близко, у меня была куча других ошибок, которые я смог решить, но не могу передать эту ошибку "В файле из", поскольку яне могу понять, что это значит.Я проверил только один класс своей карты, и он функционирует как задумано.

Вот мой код Pile.h:

#ifndef PILE_H
#define PILE_H
#include <vector>
#include "card.h"

using namespace std;

class Pile 
{
protected:
    vector<Card> p;

public:

    Pile();
    Pile(vector<Card> p);

    Card dealCard();
    int getCount();
    void shuffle();
    void clear();
    Pile operator + (const Card& c) const;
    Pile operator + (Pile& b);
    friend ostream& operator << (ostream& out, const Pile& p);

};

, а вот мой код Pile.cpp:

#include "Pile.h"
#include <iomanip>
#include <algorithm>  //shuffle
#include <time.h>
#include <sstream>
#include <stdexcept>
#include <cstdlib>

using namespace std;

Pile::Pile()
{
    p = vector<Card>(0);
}

Pile::Pile(vector<Card> p)
{
    this->p = p;
}

//draws card from the top of the pile and removes it from the vector
Card Pile:: dealCard()
{
    if(p.size() > 0)
    {
        Card tempCard = p.front();
        p.erase(p.begin());

        return tempCard;
    }
    else
        throw std::length_error("Pile is empty");


}

int Pile:: getCount()
{
    return p.size();
}

void Pile:: shuffle()
{
    srand(unsigned(time(NULL)));
    random_shuffle(p.begin(), p.end());
}

void Pile:: clear()
{
    p.clear();
}

Pile Pile:: operator + (const Card& c) const
{
    Pile tempPile(p);       //make a copy of the pile to be returned
    tempPile.p.push_back(c);  //push the new card onto the end of the pile
    return tempPile;        //return the new pile
}

Pile Pile:: operator + (Pile& b)
{
    Pile tempPile(p);

    while(b.p.size() > 0)
    {
        tempPile.p.push_back(b.p.front());
        b.p.erase(b.p.begin());
    }
    return tempPile;
}

ostream& operator << (ostream& out, const Pile& p)
{
    int count = 0;
    int index = 0;

    while(p.p.size() > 0)
    {
        out << p.p[index] << setw(2);
        count++;
        index++;

        if(count == 10)
        {
            out << endl;
            count = 0;
        }
    }
}

Мое лучшее предположение, что, возможно, я где-то пропускаю #include.Я пытался погуглить проблему в течение последних нескольких часов, и единственное, что я могу придумать, это переместить «используя пространство имен std», но я попробовал это, и я все еще получаю ошибку.

Редактировать:

Вот мой Card.cpp

#include <cstdlib>
#include "card.h"
#include <sstream>
#include <stdexcept>
using namespace std;

Card::Card(int r, char s)
{
    if(r <= 13 && r > 0)
        this->r = r;
    else
        throw std::invalid_argument("Rank must be valid (1-13)");

    if(s == 'd' || s == 'D')        //diamonds
        this->s = 'D';
    else if(s == 'h' || s == 'H')   //hearts
        this->s = 'H';
    else if(s == 's' || s == 'S')   //spades
        this->s = 'S';
    else if(s == 'c' || s == 'C')   //clubs
        this->s == 'C';
    else
        throw std::invalid_argument("Suit must be valid (H, S, C, D");
}

Card::Card(const Card& old)
{
    r = old.r;
    s = old.s;
}

void Card::setCard(int r, char s)
{
    if(r <= 13 && r > 0)
        this->r = r;
    else
        throw std::invalid_argument("Rank must be valid (1-13)");

    if(s == 'd' || s == 'D')        //diamonds
        this->s = 'D';
    else if(s == 'h' || s == 'H')   //hearts
        this->s = 'H';
    else if(s == 's' || s == 'S')   //spades
        this->s = 'S';
    else if(s == 'c' || s == 'C')   //clubs
        this->s == 'C';
    else
        throw std::invalid_argument("Suit must be valid (H, S, C, D");
}

int Card::getRank()
{
    return r;
}

 bool Card:: operator == (const Card c) const
 {
     if(r == c.r)
         return true;
     else
         return false;
 }

 bool Card:: operator >(const Card c) const
 {
     if(r > c.r)
         return true;
     else
         return false;
 }

 ostream& operator << (ostream& out, const Card c)
 {
     if(c.r == 1)
         out << "A" << c.s;
     else if(c.r > 1 && c.r <= 10)
         out << c.r << c.s;
     else if(c.r == 11)
         out << "J" << c.s;
     else if(c.r == 12)
         out << "Q" << c.s;
     else      //must be king
         out << "K" << c.s;
 }

и card.h:

#ifndef CARD_H
#define CARD_H

#include <string>
#include <iostream>
using namespace std;

class Card
{
private:
    int r;      
    char s;

public:

    Card(int r, char s); //parameterized constructor
    Card(const Card& old);     //copy constructor

    void setCard(int r, char s);
    int getRank();
    bool operator ==(const Card c) const;
    bool operator >(const Card c) const;
    friend ostream& operator << (ostream& out, const Card c);

};

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

Проблема заключается в следующей строке:

p = vector<Card>(0);

Для инициализации векторов таким способом требуется конструктор по умолчанию.Пожалуйста, смотрите std :: vector constructor (3) .Вы можете просто удалить эту строку, поскольку она действительно не нужна.std::vector все равно начинается как пустой, поэтому нет необходимости выполнять избыточную работу.

Вы увидите, что если вы удалите эту строку, вы заметите, что ваш код будет компилироваться без использования конструктора по умолчанию,Однако, если вы добавите больше кода, вы должны быть осторожны, если вы не используете std::vector так, как необходим конструктор по умолчанию.Таким образом, может не помешать просто предоставить конструктор по умолчанию.


Сказав это, ваш код выдал несколько предупреждений, которые вам необходимо устранить.Например, в ваших перегруженных << операторах вы не смогли вернуть значение.Возврат ничего из функции, которая должна возвращать значение, приводит к неопределенному поведению .

Другая проблема заключается в том, что вам не нужно писать пользовательский конструктор копирования дляPile или Card, поскольку оба класса имеют все свои члены, содержащие правильную семантику копирования (int, char для класса Card и std::vector<Card> для класса Pile).Нет необходимости вводить код, который компилятор предоставляет вам бесплатно, без ошибок и является эффективным.

0 голосов
/ 30 ноября 2018

Конструктор по умолчанию для класса Card отсутствует.C ++ не генерирует конструктор по умолчанию, когда в классе присутствует пользовательский конструктор (с параметрами или без параметров).В вашем коде необходим конструктор по умолчанию в Pile.cpp: 27.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...