带错误的“包含在错误中的文件中”

时间:2018-11-30 03:33:04

标签: c++ vector

我正在尝试创建一个以Cards为向量的聚合类,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。在过去的几个小时中,我尝试使用Google搜索这个问题,唯一能想到的就是移动“使用命名空间标准”,但我仍然尝试过,但仍然出现错误。

编辑:

这是我的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 :(得分:3)

问题是这一行:

p = vector<Card>(0);

以这种方式初始化向量需要默认的构造函数。请参阅std::vector constructor (3)。您可以简单地删除该行,因为确实没有必要。 std::vector无论如何都是空的,因此不需要做多余的工作。

您将看到,如果删除该行,则会注意到您的代码将在不需要默认构造函数的情况下进行编译。但是,如果添加更多代码,则需要小心,不要以需要默认构造函数的方式使用std::vector。因此,仅提供默认构造函数可能不会有任何伤害。


话虽如此,您的代码产生了一些需要解决的警告。例如,在重载的<<运算符中,您无法返回值。从应该返回值的函数不返回任何内容会导致未定义行为

另一个问题是,您无需为PileCard编写用户定义的副本构造函数,因为这两个类的所有成员都包含正确的副本语义({{ 1}},int(用于char类,Card用于std::vector<Card>类)。无需介绍编译器免费提供给您的代码,没有错误,而且效率很高。

答案 1 :(得分:0)

缺少Card类的默认构造函数。当类中存在用户定义的构造函数(带参数或不带参数)时,C ++不会生成默认构造函数。 在您的代码中,Pile.cpp:27中需要默认构造函数。