【问题标题】:vector.push_back not working on template class C++vector.push_back 不适用于模板类 C++
【发布时间】:2021-06-03 17:53:29
【问题描述】:

所以我编写了该代码,它获取一个用于读取的 in 文件,将其读入一个对象的临时变量,然后将其 push_back 到一个向量作为容器。 但是......它不起作用,在最后一个之后,所有变量都获取文件中读取的最后一个对象的信息!

setObject 类:

template <typename Objeto, typename Container>
void setObjetos(const string& nome, Container& objetos){
    ifstream in (nome.c_str());
    Objeto temporario;
    while(in >> temporario){
        cout << "temporario: " << temporario << endl;
        objetos.push_back(temporario);
        cout << "Objetos.front():" << objetos.front() << endl;
        cout << "Objetos.back():" << objetos.back() << endl;
    }
    in.close();
    for (auto it : objetos) {
        cout << "Objeto it em set apos while: "<< endl << it;
    }
}

然后,我得到了那个调用它的类,例如: 该类接收一个对象进行验证,然后,我从“SetObjectos”获取对象容器并进行一些比较:

template <typename Objeto>
template <typename Objeto, typename Container>
int verifica(Objeto objeto, const string& nome){
    existe(nome);
    Container objetos;
    setObjetos<Objeto, Container>(nome, objetos);
    for (auto it : objetos) {
        cout << "Objeto it: "<< endl << it;
        if (strcmp(it.getChave(), objeto.getChave()) == 0){
            return 1;
        }
    }
    return 0;
}

这就是我在登录情况下调用验证函数的方式:

void Clinica::login(const string& arquivo)
    {
        char* usuario = new char[12];
        char* senha = new char[12];
        cout << endl << "INSIRA O USUARIO: ";
        cin >> usuario;
        cout << endl << "INSIRA A SENHA: ";
        cin >> senha;
        Usuario user(usuario, senha, '0');
        user.setChave();
        if (!verifica<Usuario, vector<Usuario>>(user, arquivo)){
            cout << endl << "USUARIO OU SENHA INVALIDOS!" << endl;
        }else{
            Usuario temp = getObjeto<Usuario>(user, arquivo);
            if (strcmp(temp.getSenha(), user.getSenha()) == 0){
                user = temp;
                temp.~Usuario();
                switch (user.getTipo()) {
                    case 'A':
                        this->menuAdministrador(user);
                    break;

                    case 'B':
                        this->menuAssistenteAdministrativo(user);
                    break;

                    case 'G':
                        this->menuUsuarioGeral(user);
                    break;
                }
            }else{
                cout << endl << "USUARIO OU SENHA INVALIDOS!" << endl;
            }
        }
    }

然后,这就是我的用户对象:

#include "usuario.hpp"

        Usuario::Usuario(){}

        Usuario::Usuario(const char usuario[12], const char senha[12], const char& tipo):
        usuario((char*)usuario), senha((char*)senha), tipo(tipo){}

        Usuario::~Usuario(){}

        void Usuario::setUsuario(const char usuario[12]){
            this->usuario = (char*)usuario;
        }

        void Usuario::setSenha(const char senha[12]){
            this->senha = (char*)senha;
        }

        void Usuario::setTipo(const char tipo){
            this->tipo = tipo;
        }

        char* Usuario::getUsuario(){
            return this->usuario;
        }

        char* Usuario::getSenha(){
            return this->senha;
        }

        char Usuario::getTipo(){
            return this->tipo;
        }

        void Usuario::setChave(char* chave){
            this->chave.setChave( chave );
        }

        void Usuario::setChave(){
            this->chave.setChave( usuario );
        }

        char* Usuario::getChave(){
            return this->chave.getChave();
        }

        ostream& operator <<(ostream& out, const Usuario& user){
            out << user.chave << "\n" << user.usuario << "\n" << user.senha << "\n" << user.tipo << endl;
            return out;
        }

        istream& operator >>(istream& in, Usuario& user){
            in >> user.chave;
            in >> user.usuario; 
            in >> user.senha; 
            in >> user.tipo;
            return in;
        }

这得到了一个公开的 uhhh 我真的不知道它的英文名字,我们在葡萄牙语中称之为 herança,而 java 它的类似扩展......但我想你们知道我的意思......好吧用户扩展自Chave,这是每个类都有的唯一键,所以当我想在我的模板类中进行一些比较和内容时:

#include "chave.hpp"

Chave::Chave(){}

Chave::~Chave(){}

void Chave::setChave(char* chave){
  this->chave = chave;
}

char* Chave::getChave(){
  return this->chave;
}

ostream& operator<<(ostream& out, const Chave& chave){
  out << chave.chave;
  return out;
}

istream& operator>>(istream& in, Chave& chave){
  in >> chave.chave;
  return in;
}

代码示例输出:

temporario: admin
admin
admin
A

Objetos.front():admin
admin
admin
A

Objetos.back():admin
admin
admin
A

temporario: teste
teste
testando
G

Objetos.front():teste
teste
testando
A

Objetos.back():teste
teste
testando
G

temporario: 1'244
1'244
134223
G

Objetos.front():1'244
1'244
134223
A

Objetos.back():1'244
1'244
134223
G

temporario: 43987523987dhgdfhjfd
43987523987dhgdfhjfd
fsdjikughfkfhdg
G

Objetos.front():43987523987dhgdfhjfd
43987523987dhgdfhjfd
fsdjikughfkfhdg
A

Objetos.back():43987523987dhgdfhjfd
43987523987dhgdfhjfd
fsdjikughfkfhdg
G

Objeto it em set apos while: 
43987523987dhgdfhjfd
43987523987dhgdfhjfd
fsdjikughfkfhdg
A
Objeto it em set apos while: 
43987523987dhgdfhjfd
43987523987dhgdfhjfd
fsdjikughfkfhdg
G
Objeto it em set apos while: 
43987523987dhgdfhjfd
43987523987dhgdfhjfd
fsdjikughfkfhdg
G
Objeto it em set apos while: 
43987523987dhgdfhjfd
43987523987dhgdfhjfd
fsdjikughfkfhdg
G
Objeto it: 
43987523987dhgdfhjfd
43987523987dhgdfhjfd
fsdjikughfkfhdg
A
Objeto it: 
43987523987dhgdfhjfd
43987523987dhgdfhjfd
fsdjikughfkfhdg
G
Objeto it: 
43987523987dhgdfhjfd
43987523987dhgdfhjfd
fsdjikughfkfhdg
G
Objeto it: 
43987523987dhgdfhjfd
43987523987dhgdfhjfd
fsdjikughfkfhdg
G

最后出现的是用户提示的一个字符,第一个是key,然后是用户名,然后是密码。

这就像推回的功能不起作用!开始时的对象应始终是 admin,但它会被后面的对象替换,然后,在此之后,向量中的每个变量都将被重写为 char 类型 val 旁边输入的最后一个对象。

那个方法奏效了……就像今天一样! 然后那开始发生了! 有人能帮我吗? 感谢大家的阅读和帮助

如果你们想要更好的视图,这里是代码的 repo: https://github.com/bruno-augusto-pinto/TP01-CPLUSPLUS

【问题讨论】:

  • 形成一个正确的minimal reproducible example,包括生成输出的测试数据,以及设置和调用函数的代码。我们只能猜测Container 是什么,Objeto 与它的关系等等,我们不应该(猜测,就是)。我特别感兴趣的是看到您的operator &gt;&gt; 过载,这是您的minimal reproducible example 的一部分,以及Objeto 的定义和操作。
  • 我填写了足够多的空白来让您的模板实例化和执行。在那个特定的例子中它工作得很好。因此,您需要提供更多信息(即上述minimal reproducible example)。
  • 我运行了你的代码(除了我使用了std::stringstream),一切都按预期工作。你如何实例化setObjetos
  • 它适用于我 - 这是一个 MVCE:onlinegdb.com/BJ6txXk7O 有了它,您需要传递一个模板参数 - 这是一个不需要任何模板参数的版本:onlinegdb.com/SJjCxm1md
  • @WhozCraig,嘿,我在我的身体问题中添加了更多信息,我想这会有所帮助!

标签: c++ templates vector push-back


【解决方案1】:
 Container objetos;

这是本地的并被丢弃。

您的 Usuario 需要使用标准字符串,而不是原始 C 缓冲区。它可能使用了悬空指针。

【讨论】:

  • 嘿,我会试试的。第一次我是用真正的字符串做的!但是我的老师说如果我使用字符串我以后不能直接删除文件中的objetc,这是真的吗?谢谢
  • @BernardoEmery 您不能删除由 strings 管理的字符,但如果您反过来 newd 则可以删除包含字符串的对象。但我没有看到您的问题中有任何需要您致电 newdelete
  • 嘿,好吧,为了删除文件中的内容,我将它放到向量中,在向量中找到它,执行 vector.erase(it),然后重写整个文件。你认为有更好的方法吗?
猜你喜欢
  • 2023-02-22
  • 2017-11-15
  • 1970-01-01
  • 2018-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-23
相关资源
最近更新 更多