简体   繁体   English

C ++错误:类型名称未知

[英]C++ error: unknown type name

So, here's my code: 所以,这是我的代码:

/****************************************************************
File:             Video.h
Description:      class declarations

Author:           David && Evan
Class:            CSCI 120
Date:             2015 May 13

We hereby certify that this program is entirely our own work.
*****************************************************************/

#ifndef VIDEO_H
#define VIDEO_H

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

#include "Person.h"
#include "Date.h"

using namespace std;

enum kind {MOVIE, TELEVISION, COMPUTER};
// 'MOVIE' = standalone film of any length, whether it's part of a franchise or not
// 'TELEVISION' = episode from mini- or recurring series
// 'COMPUTER' = online or locally hosted files
/* If need be, we can extend this by adding something for analog home movies, 
i.e., camcorder tapes or 8mm film. */

namespace Vids
{

    class Video{

        public:
            Video(); // default constructor
            Video(string name, string audience, string location, vector<Person> directors,
                vector<Person> actors, Date released);
            virtual void display() = 0; // displays information for all objects of Video type
            virtual void displayAll() = 0; // displays all information for one object
            unsigned char getDirectorSize() const { return directorSize; }
            unsigned char getActorSize() const { return actorSize; }
            string getName() const { return name; }
            string getAudience() const { return audience; }
            string getLocation() const { return location; }
            Date getReleased() const { return released; }
            Date getViewed() const { return viewed; }
            string Truncate(string str, size_t width) { // shortens output
                if (str.length() > width)
                    return str.substr(0, width) + "...";
                return str;
            }   // truncate

        protected:
            short runtimeMinutes;
            /* Theoretically runtime could be unsigned, but we might eventually 
            need negatives for special values.  I doubt we'll see one needing 
            more than 32K minutes, so no worry about overflow. */
            unsigned char directorSize;
            // number of elements in each vector, shouldn't need more than 255
            unsigned char actorSize;
            string name;    // title of movie
            string audience;    // PG = "Plenty Guns", PG-13 = "13 or more guns"
            string location;
            /* Location is a catch-all field for: URL, shelf disc is on, format 
            type, name of person it is loaned to, etc. */
            vector<Person> directors(directorSize);
            /* David: I considered using other containers, but none of them 
            offered any obvious benefits over the vector. */
            vector<Person> actors(actorSize);
            Date released;
            Date viewed;
            /* 'viewed' can be used to answer the question: "What haven't i 
            watched lately?" */

    };  // end class Video

} // end namespace Vids

#endif

And compiling [with several other files] gives me this: 和编译[与其他几个文件]给了我这样的:

$ g++ *.cpp -o Project3

In file included from Computer.cpp:12:
In file included from ./Computer.h:15:
./Video.h:68:29: error: unknown type name 'directorSize'
vector<Person> directors(directorSize);
                         ^
./Video.h:71:26: error: unknown type name 'actorSize'
vector<Person> actors(actorSize);
                      ^

directorSize is declared in the same scope as directors, so why is the compiler not recognizing it? directorSize的声明范围与director相同,那么为什么编译器无法识别它?

The line 线

vector<Person> directors(directorSize);

is not the right syntax for declaring a member variable. 声明成员变量的语法不正确。

Change it to 更改为

vector<Person> directors;

Similarly, change 同样,改变

vector<Person> actors(actorSize);

to

vector<Person> actors;

Given that you can get the number of items in a vector by calling the size() member function, you don't need the member variables: 假定您可以通过调用size()成员函数来获得vector的项目数,则不需要成员变量:

unsigned char directorSize;
unsigned char actorSize;

Remove them. 删除它们。

Well, this comment is puzzling: 好吧,这个评论令人困惑:

/* Theoretically runtime could be unsigned, but we might eventually 
        need negatives for special values.  I doubt we'll see one needing 
        more than 32K minutes, so no worry about overflow. */
        unsigned char directorSize;

unsigned char maxes out at 255 so if you need up to 32K then you will have to use a different type. unsigned char255因此如果您最多需要32K,则必须使用其他类型。 In fact it would be better to remove this variable entirely, and retrieve the size by doing directors.size() as needed. 实际上,最好完全删除此变量,并根据需要通过执行directors.size()来检索大小。

It is possible to initialize the vector in the class definition: 可以在类定义中初始化向量:

vector<Person> directors{directorSize};

However this would cause undefined behaviour if you hadn't initialized directorSize in the constructor initializer list (because you would be using an uninitialized variable directorSize ). 但是,如果您没有在构造函数初始化器列表中初始化directorSize ,这将导致未定义的行为(因为您将使用未初始化的变量directorSize )。

It would be much better to change this to: 将其更改为:

vector<Person> directors;

and presumably in your constructor initializer list, or constructor body, you will add some items into this vector. 大概在构造函数初始值设定项列表或构造函数主体中,您将向此向量添加一些项目。

I'll boil your problem down to a trivial case to demonstrate the problem, along with applying the "m_" member variable prefix popular among some engineers for highlighting a variable that is a "member" of something. 我将您的问题简化为一个简单的案例来说明问题,并应用在某些工程师中流行的“ m_”成员变量前缀来突出显示某个事物的“成员”变量。

#include <vector>

class Class {
protected:
    unsigned char m_directorSize;
    std::vector<int> m_directors(m_directorSize);
};

int main()
{
    Class x;
}

This does not compile http://ideone.com/VJck4Q and by isolating the problem, we learned a lot. 这不能编译http://ideone.com/VJck4Q ,通过隔离问题,我们学到了很多东西。

The line of code: 代码行:

    std::vector<int> m_directors(m_directorSize);

Look at the syntax of this 看一下这个语法

    /typename/ /name/ ( /values/ );

The compiler thinks this is a member-function declaration, which is why it is expecting a type: 编译器认为这是成员函数声明,这就是为什么要使用类型的原因:

    std::vector<int> something(unsigned char directorSize);

would declare a member-function called "something" that takes a parameter, directorSize, of type unsigned char . 会声明一个名为“ something”的成员函数,该函数带有unsigned char类型的参数DirectorSize。 Incidentally: unsigned char is almost guaranteed to be an 8-bit value, capable of storing 0 through 255. That's a terrible choice for a size variable. 顺便说一句: unsigned char几乎可以保证是8位值,能够存储0到255。这对于size变量来说是一个糟糕的选择。 There is a standard type, size_t for storing non-negative sizes and ssize_t for storing signed sizes. 有一个标准类型, size_t用于存储非负大小, ssize_t用于存储带符号的大小。

It's unclear why you think you should be passing directorSize to the vector, but you can't declare a member with a function call. 目前尚不清楚为什么您认为应该将DirectorSize传递给向量,但是无法通过函数调用声明成员。

If you want to shape the default behavior of an object at construction time of your class, you need to use a constructor (or use C++11/C++14, but we don't know if you're doing that): 如果要在类构造时塑造对象的默认行为,则需要使用构造函数(或使用C ++ 11 / C ++ 14,但我们不知道您是否正在这样做) :

class Foo_Sized {
    std::vector<int> m_vec;
public:
    Foo() : m_vec(250)  // default construct 250 elements
    {}
};

If you were using C++11/14: 如果您使用的是C ++ 11/14:

class Foo_Sized {
    std::vector<int> m_vec = std::vector<int>(250);
};

But if you want to affect one member based on the value of another, the only place you can do that is in a member function, so in this case that means the constructor. 但是,如果要基于另一个成员的值影响一个成员,则只能在成员函数中执行此操作,因此在这种情况下,这意味着构造函数。

If you're going to create a static array like that, you probably want to be using std::array instead of std::vector - the whole point of vector is that it can grow dynamically. 如果你要创建一个静态数组一样,你可能要使用std::array代替std::vector -整点vector是它可以动态增长。

std::array<int, 250> m_arr;

This declares an array of integers which has a capacity of 250 and has a fixed size. 这声明了一个整数数组,其容量为250,并且具有固定大小。 It's faster than a vector but it is always 250 large. 它比矢量要快,但始终为250大。 You would then have to track the "in-use" count of it and other management overhead yourself. 然后,您必须自己跟踪它的“使用中”计数和其他管理开销。

std::vector<int> vec;
std::cout << vec.size() << '\n';    // prints 0
vec.push(10);  // add a value of 10 to the vector.
vec.push(20);  // vec is now { 10, 20 }
std::cout << vec.size() << '\n';    // prints 2
vec.push(30);  // vec is now { 10, 20, 30 }
std::cout << vec.size() << '\n';    // prints 3
std::cout << vec[0] << '\n'; // prints 10
std::cout << vec[3] << '\n'; // undefined behavior, there is no 3rd element

std::array<int, 3> arr;
std::cout << arr.size() << '\n'; // prints 3: fixed size.
arr[0] = 10;                     // can't push, fixed size.
arr[1] = 20;
std::cout << arr.size() << '\n'; // still 3, always will be.
arr[2] = 30;
std::cout << arr.size() << '\n'; // still 3, always will be.
std::cout << arr[0] << '\n';     // prints 10
std::cout << arr[3] << '\n';     // compile error: outside fixed size

If you were worrying about memory allocation, you could tell the vector to allocate memory upfront like this: 如果您担心内存分配,可以告诉向量预先分配内存,如下所示:

class Foo_Reserved {
    std::vector<int> m_vec;
public:
    Foo() : m_vec()     // default construct empty
    {
        m_vec.reserve(250); // reserve memory for 250 elements
    }
};

There are a host of other issues with your code, but they aren't directly related to your question so I'm not going to address/highlight them. 您的代码还有很多其他问题,但是它们与您的问题没有直接关系,因此我不会解决/强调它们。

But in terms of dealing with your directorSize issues, you should consider providing an accessor that queries the vector or expose a const reference to the vector (this somewhat breaks encapsulation tho since it allows external callers to write code based on assumptions about your internal structure). 但就处理DirectorSize问题而言,您应考虑提供一个访问器,该访问器可查询向量或公开对向量的const引用(这在某种程度上破坏了封装方法,因为它允许外部调用者根据有关内部结构的假设来编写代码) 。

class Foo {
public:
    using vec_t = std::vector<int>;
protected:
    vec_t m_vec;
public:
    Foo() : m_vec()     // default construct empty
    {
    }

    size_t vecSize() const { return m_vec.size(); }
    // or, return a look-don't-touch reference to the vector
    const vec_t& getVec() const { return m_vec; }
};

Foo f{};   // C++14 initializer
f.vecSize();
f.getVec().size();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM