繁体   English   中英

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

[英]C++ error: unknown type name

所以,这是我的代码:

/****************************************************************
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

和编译[与其他几个文件]给了我这样的:

$ 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的声明范围与director相同,那么为什么编译器无法识别它?

线

vector<Person> directors(directorSize);

声明成员变量的语法不正确。

更改为

vector<Person> directors;

同样,改变

vector<Person> actors(actorSize);

vector<Person> actors;

假定您可以通过调用size()成员函数来获得vector的项目数,则不需要成员变量:

unsigned char directorSize;
unsigned char actorSize;

删除它们。

好吧,这个评论令人困惑:

/* 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 char255因此如果您最多需要32K,则必须使用其他类型。 实际上,最好完全删除此变量,并根据需要通过执行directors.size()来检索大小。

可以在类定义中初始化向量:

vector<Person> directors{directorSize};

但是,如果您没有在构造函数初始化器列表中初始化directorSize ,这将导致未定义的行为(因为您将使用未初始化的变量directorSize )。

将其更改为:

vector<Person> directors;

大概在构造函数初始值设定项列表或构造函数主体中,您将向此向量添加一些项目。

我将您的问题简化为一个简单的案例来说明问题,并应用在某些工程师中流行的“ m_”成员变量前缀来突出显示某个事物的“成员”变量。

#include <vector>

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

int main()
{
    Class x;
}

这不能编译http://ideone.com/VJck4Q ,通过隔离问题,我们学到了很多东西。

代码行:

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

看一下这个语法

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

编译器认为这是成员函数声明,这就是为什么要使用类型的原因:

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

会声明一个名为“ something”的成员函数,该函数带有unsigned char类型的参数DirectorSize。 顺便说一句: unsigned char几乎可以保证是8位值,能够存储0到255。这对于size变量来说是一个糟糕的选择。 有一个标准类型, size_t用于存储非负大小, ssize_t用于存储带符号的大小。

目前尚不清楚为什么您认为应该将DirectorSize传递给向量,但是无法通过函数调用声明成员。

如果要在类构造时塑造对象的默认行为,则需要使用构造函数(或使用C ++ 11 / C ++ 14,但我们不知道您是否正在这样做) :

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

如果您使用的是C ++ 11/14:

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

但是,如果要基于另一个成员的值影响一个成员,则只能在成员函数中执行此操作,因此在这种情况下,这意味着构造函数。

如果你要创建一个静态数组一样,你可能要使用std::array代替std::vector -整点vector是它可以动态增长。

std::array<int, 250> m_arr;

这声明了一个整数数组,其容量为250,并且具有固定大小。 它比矢量要快,但始终为250大。 然后,您必须自己跟踪它的“使用中”计数和其他管理开销。

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

如果您担心内存分配,可以告诉向量预先分配内存,如下所示:

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

您的代码还有很多其他问题,但是它们与您的问题没有直接关系,因此我不会解决/强调它们。

但就处理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