[英]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 char
为255
因此如果您最多需要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.