C++ 错误:请求成员...这是非类类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18806285/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
error: request for member ... which is of non-class type
提问by badger0053
I realize the error is coming from using vectors in a custom class, but I have been struggling how to fix them. How do I call vector methods when its part of the class object?
我意识到错误来自在自定义类中使用向量,但我一直在努力修复它们。当它是类对象的一部分时,如何调用向量方法?
These are the errors I am getting:
这些是我得到的错误:
Word.cpp: In member function ‘void Word::addPosition(int)':
Word.cpp:20: error: request for member ‘push_back' in ‘((Word*)this)->Word::positions', which is of non-class type ‘std::vector<int, std::allocator<int> >*'
Word.cpp: In member function ‘int Word::getPosition(int)':
Word.cpp:26: error: request for member ‘size' in ‘((Word*)this)->Word::positions', which is of non-class type ‘std::vector<int, std::allocator<int> >*'
Word.cpp:27: error: request for member ‘size' in ‘((Word*)this)->Word::positions', which is of non-class type ‘std::vector<int, std::allocator<int> >*'
Word.cpp:29: error: cannot convert ‘std::vector<int, std::allocator<int> >' to ‘int' in return
Header
标题
#pragma once
#include <string>
#include <vector>
class Word {
public:
Word();
~Word();
void setWord(std::string);
void addPosition(int);
std::string getWord();
int getPosition(int);
private:
std::string word;
std::vector<int> *positions;
};
Implementation
执行
#include "Word.h"
#include <string>
#include <vector>
Word::Word() {
this->word = "";
this->positions = new std::vector<int>(5);
}
void Word::setWord(std::string s) {
this->word = s;
}
void Word::addPosition(int i) {
this->positions.push_back(i);
}
std::string Word::getWord() {
return this->word;
}
int Word::getPosition(int i) {
if (i < this->positions.size() && i > 0) {
for (int j = 0; j < this->positions.size(); i++) {
if (i == j) {
return positions[j];
}
}
}
return -1;
}
edit: Is this a better way to set up the class? header:
编辑:这是设置课程的更好方法吗?标题:
#pragma once
#include <string>
#include <vector>
class Word {
public:
Word();
~Word();
void setWord(std::string);
void addPosition(int);
std::string getWord();
int getPosition(int);
private:
std::string word;
std::vector<int> positions;
};
implementation:
执行:
Word::Word(){
word = "";
}
void Word::setWord(std::string s){
this -> word = s;
}
void Word::addPosition(int i){
this -> positions.push_back(i);
}
std::string Word::getWord(){
return this -> word;
}
int Word::getPosition(int i){
if (i < this -> positions.size() && i > 0) {
for (int j = 0; j<this -> positions.size(); i++) {
if (i == j) {
return (this->positions)[j];
}
}
}
return -1;
}
but now I am getting this error:
但现在我收到此错误:
Undefined symbols for architecture x86_64:
"_main", referenced from:
start in crt1.10.6.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
采纳答案by Chris Hayes
positions
is a pointer. You need to dereference it in order to get to the base vector:
positions
是一个指针。您需要取消引用它才能获得基本向量:
this->positions->size();
this->positions->size();
In general, the error you're getting is caused by failing to dereference (because T*
is not a class type; it's a pointer, and pointers are a primitive type).
通常,您得到的错误是由于未能取消引用引起的(因为T*
它不是类类型;它是指针,而指针是原始类型)。
回答by Manu343726
In addition to @Chris answer, the de facto problem here is that you are using a pointer to a vector instead of a vector directly.
There is no reason to allocate dynamically a vector, because it internally uses dynamic memory to store its elements. The advantage of vector is that it manages its own memory, and that memory its released at the end of its scope: Thats RAII.
除了@Chris 的回答之外,这里的实际问题是您使用的是指向向量的指针,而不是直接使用向量。
没有理由动态分配向量,因为它内部使用动态内存来存储其元素。vector 的优点是它管理自己的内存,并且在其作用域结束时释放该内存:这就是RAII。
Personally I recommend the Going Native 2013 Stroupstrup talk "The Essence of C++". He provides pretty examples and explanations about data management in C++: Data vs Handlers of data.
我个人推荐 Going Native 2013 Stroustrup 演讲“C++ 的本质”。他提供了有关 C++ 中数据管理的漂亮示例和解释:数据与数据处理程序。
For those coming from Java: A perspective about memory management in Java and C++
对于那些来自 Java 的人:关于 Java 和 C++ 中的内存管理的一个观点
In Java we differentiate two kinds of data: Basic types (Ints, chars, booleans, etc), and objects (Instances of classes).
Java manages its memory through a Garbage Collector: The Java runtime (The JVM) allocates the memory used by objects on the heap, and what provides you is a pointer to that allocated object. So in Java your variables are really pointers allocated on the stack pointing to the heap memory where the object is allocated(This is directly related with the usual problems which noobs have with Java pass by value). This allows Java to share ownership of object instances easily: It only tracks (via reference counting) how many variables refers to an specific object.
Occasionally the garbage collector look at the program heap and releases the memory used by objects which reference count have dropped to zero (That is, objects which you are not using yet). So, as you can see, The GC provides a non-deterministic way to release/manage the memory.
在 Java 中,我们区分两种数据:基本类型(整数、字符、布尔值等)和对象(类的实例)。Java 通过垃圾收集器管理其内存:Java 运行时(JVM)分配堆上对象使用的内存,并且为您提供指向该分配对象的指针。因此,在 Java 中,您的变量实际上是分配在堆栈上的指针,指向分配对象的堆内存(这与新手在 Java 中按值传递的常见问题直接相关)。这允许 Java 轻松共享对象实例的所有权:它仅跟踪(通过引用计数)有多少变量引用了特定对象。
有时,垃圾收集器会查看程序堆并释放引用计数已降至零的对象(即您尚未使用的对象)所使用的内存。因此,如您所见,GC 提供了一种非确定性的方式来释放/管理内存。
C++ memory management is dessigned to work in a deterministic way. All variables are declared in a specific scope, which determines its lifetimeWhen the scope of a variable ends, the lifetime of that variable ends, and in the case of objects, its destructor its called to execute the apropiated releasing operations.
Thats known as Resource Acquisition Is Initialization, or RAII.
C++ 内存管理被设计为以一种确定性的方式工作。所有变量都在一个特定的范围内声明,这决定了它的生命周期当一个变量的范围结束时,该变量的生命周期结束,对于对象,它的析构函数被调用以执行适当的释放操作。
这就是所谓的资源获取即初始化,或 RAII。
RAII means that objects manage resources (Memory, file handles, network ports, etc), and the adquisition, use, and release of that resource is directly linked to the lifetime of the object which manages the resource. This provides a deterministic and leak-free system to manage resources: Note that "resources" don't refers to memory only, which is the only resource which a Garbage Collector manages. RAII is, in the 99% of the cases, much more powerfull and secure than a garbage collector.
RAII 意味着对象管理资源(内存、文件句柄、网络端口等),该资源的获取、使用和释放与管理资源的对象的生命周期直接相关。这提供了一个确定性和无泄漏的系统来管理资源:请注意,“资源”不仅仅指内存,这是垃圾收集器管理的唯一资源。在 99% 的情况下,RAII比垃圾收集器更强大和安全。
std::vector
is the tipical example of a class that manages a resource (A dynamically allocated resizable array in its case) through RAII.
As you can see, I havent talk about pointers at all: Pointers have to be used to share ownership of an object, or to allocate a dynamic chunk (Array) of memory. But note that the first case could be (And must be) achieved through smart pointers, and the second through RAII-based containers such as std::vector
.
std::vector
是通过 RAII 管理资源(在其情况下为动态分配的可调整大小的数组)的类的典型示例。
如您所见,我根本没有谈论指针:必须使用指针来共享对象的所有权,或分配内存的动态块(数组)。但请注意,第一种情况可以(并且必须)通过智能指针实现,第二种情况通过基于 RAII 的容器,例如std::vector
.
The problem with your use of a pointer to dynamically-allocate a std::vector
are:
使用指针动态分配 a 的问题std::vector
是:
std::vector
manages internally a dynamic array where it allocates the elements, sostd::vector
size (That is, what vector fits in the stack) its only the size of the pointer pointing to the array, and two counters (Integers). Don't worry about the size of vector in the stack (Due to possible stackoverflows): The array is allocated on the heap.Using a pointer to allocate dynamically a vector breaks RAII, because the lifetime of the vector instance is not linked to any scope, its lifetime must be determined by you, when you decide to deallocate (
delete
) the vector. Of course manual dynamic memory management its error prone.
std::vector
在内部管理一个动态数组,在其中分配元素,因此std::vector
大小(即适合堆栈的向量)仅是指向数组的指针的大小和两个计数器(整数)。不要担心堆栈中向量的大小(由于可能的堆栈溢出):数组是在堆上分配的。使用指针动态分配向量会破坏 RAII,因为向量实例的生命周期没有链接到任何作用域,它的生命周期必须由您决定,当您决定解除分配 (
delete
) 向量时。当然手动动态内存管理容易出错。
Again, I recommend you to view Stroupstrup's talk: He explains this much better than me :)
再次,我建议您查看 Stroustrup 的演讲:他对此的解释比我好得多:)
回答by 0x499602D2
positions
is a pointer, so you need to use indirection:
positions
是一个指针,所以你需要使用间接:
this->positions->push_back(i);
Don't use pointers in this situation. You're better off using a stack-allocated vector and initializing it through the constructor:
在这种情况下不要使用指针。您最好使用堆栈分配的向量并通过构造函数对其进行初始化:
class Word
{
...
private:
std::string word;
std::vector<int> positions;
};
Word::Word()
: word(""), positions(5) { }
void Word::addPosition(int i)
{
this->positions.push_back(i);
}
回答by user1708860
positions
is a pointer to a vector, the usage should be with the ->
operator:
positions
是指向向量的指针,用法应与->
运算符一起使用:
also, notice that i changed return positions[j];
另外,请注意我改变了 return positions[j];
#include "Word.h"
#include <string>
#include <vector>
Word::Word(){
this -> word = "";
this -> positions = new std::vector<int>(5);
}
void Word::setWord(std::string s){
this -> word = s;
}
void Word::addPosition(int i){
this -> positions->push_back(i);
}
std::string Word::getWord(){
return this -> word;
}
int Word::getPosition(int i){
if (i < this -> positions.size() && i > 0) {
for (int j = 0; j<this -> positions->size(); i++) {
if (i == j) {
return (*positions)[j];
}
}
}
return -1;
}
Another solution, will be not to hold a pointer, define the vector like this:
另一种解决方案是不持有指针,像这样定义向量:
private:
std::string word;
std::vector<int> positions;
And then you should also remove this line this -> positions = new std::vector<int>(5);
You should also know that vector enlarges itself when it needs, you do not need to specify that it's initial size if it is small (you should consider doing it for realy large values)
然后你还应该删除这条线this -> positions = new std::vector<int>(5);
你还应该知道向量在需要时会放大自己,如果它很小,你不需要指定它的初始大小(你应该考虑为非常大的值这样做)
回答by ScottMcP-MVP
positions
is a pointer, so you need positions->push_back
.
positions
是一个指针,所以你需要positions->push_back
.
On the other hand, why are you allocating the vector on the heap? It can be a member of the class instead.
另一方面,为什么要在堆上分配向量?它可以是类的成员。