繁体   English   中英

错误:请求成员...这是非类型的

[英]error: request for member … which is of non-class type

我意识到错误来自于在自定义类中使用向量,但我一直在努力解决它们。 如何在类对象的一部分调用向量方法?

这些是我得到的错误:

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

#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;
};

履行

#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;
}

编辑:这是设置课程的更好方法吗? 标题:

    #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;
    };

执行:

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;
}

但现在我收到这个错误:

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

除了@Chris的答案之外,这里的事实上的问题是你正在使用指向矢量而不是矢量的指针
没有理由动态分配向量,因为它在内部使用动态内存来存储其元素。 向量的优点是它管理自己的内存,并在其范围的末尾释放它的内存:那就是RAII

我个人推荐Going Native 2013 Stroupstrup演讲“C ++的本质” 他提供了有关C ++中数据管理的相关示例和解释:数据与数据处理程序。

对于那些来自Java的人:关于Java和C ++中的内存管理的观点

在Java中,我们区分两种数据:基本类型(Ints,chars,booleans等)和对象(类的实例)。 Java通过垃圾收集器管理其内存:Java运行时(JVM)分配堆上对象使用的内存,为您提供的是指向该分配对象的指针 所以在Java中,你的变量实际上是在堆栈上分配的指针,指向分配对象的堆内存 (这与noobs通过Java传递的通常问题直接相关)。 这允许Java轻松地共享对象实例的所有权:它只跟踪(通过引用计数)有多少变量引用特定对象。
垃圾收集器偶尔会查看程序堆并释放引用计数已降至零的对象使用的内存(即,您尚未使用的对象)。 因此,正如您所看到的, GC提供了一种非确定性的方式来释放/管理内存

C ++内存管理被设计为以确定的方式工作 所有变量都在特定范围内声明, 这决定了它的生命周期当变量的范围结束时, 变量的生命周期结束,而在对象的情况下,它的析构函数被调用以执行相关的释放操作
这称为资源获取是初始化,或RAII。

RAII表示对象管理资源(内存,文件句柄,网络端口等),并且该资源的获取,使用和释放直接链接到管理资源的对象的生命周期 这提供了一个确定且无泄漏的系统来管理资源:请注意,“资源”不仅指内存,而是垃圾收集器管理的唯一资源。 在99%的情况下,RAII 比垃圾收集器更强大更安全

std::vector是通过RAII管理资源(在其情况下是动态分配的可调整大小的数组)的类的典型示例。
正如您所看到的,我根本没有谈论指针: 必须使用指针来共享对象的所有权,或者分配动态的内存块(Array) 但请注意,第一种情况可能是(并且必须)通过智能指针实现,第二种情况可以通过基于RAII的容器实现,例如std::vector

使用指针动态分配std::vector是:

  • std::vector内部管理一个动态数组,它分配元素,所以std::vector size(也就是说,什么向量适合堆栈)它只指向指向数组的指针的大小,以及两个计数器(整数) 。 不要担心堆栈中向量的大小(由于可能的堆栈溢出):数组在堆上分配。

  • 使用指针动态分配向量会中断RAII,因为向量实例的生命周期未链接到任何作用域,当您决定释放( delete )向量时,它的生命周期必须由您确定 当然手动动态内存管理容易出错。

再次,我建议你观看Stroupstrup的演讲:他比我解释得更好:)

positions是一个指针。 您需要取消引用它才能到达基本向量:

this->positions->size();

通常,您获得的错误是由于无法解除引用(因为T*不是类类型;它是指针,指针是基本类型)。

positions是一个指针,所以你需要使用间接:

this->positions->push_back(i);

在这种情况下不要使用指针 你最好使用堆栈分配的向量并通过构造函数初始化它:

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);
}

positions是指向vector的指针,用法应该是->运算符:

另外,请注意我改变了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;
}

另一个解决方案,是不要持有指针,定义这样的向量:

private:
    std::string word;
    std::vector<int> positions;

然后你也应该删除这一行this -> positions = new std::vector<int>(5); 您还应该知道向量在需要时会自动扩大,如果它很小,您不需要指定它的初始大小(您应该考虑将其用于真正的大值)

positions是一个指针,所以你需要positions->push_back

另一方面,为什么要在堆上分配向量? 它可以是该类的成员。

暂无
暂无

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

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