C ++将指针传递给Template类函数

时间:2016-12-07 11:50:10

标签: c++ c++11 pointers reference

我是C ++的新手(更像是一个java人)。我正在尝试自学C ++指针。在这里,我创建了两个类,Person(基类)和Student(派生类)。

我尝试将Student个对象放在unordered_map<string, Person>中。但遇到了错误。

这是我的代码:

class Person
{
  protected:
    string name;
    int age;

  public:
    int getAge()
    {
      return age;
    }
    string getName()
    {
      return name;
    }
};

class Student : public Person
{
  private:
    string grade;

  public:
    Student(string const &name, int const &age, string const &grade)
    {
      this -> name = name;
      this -> age = age;
      this -> grade = grade;
    }
    int getAge();
};

这是我的主要职能:

int main()
{
  unordered_map<string, Person *> students;
  Student s("Sam", 26, "A");
  Person *p;
  p = &s;

  students.insert(p -> getName(), p);

  return 0;
}

这只是代码的一部分,我知道它看起来很愚蠢。但我只是在学习指针

我已添加<iostream><unordered_map>个库,并在此处使用namespace std

错误消息太长了。有人能指出我在这里犯的错误吗?或者,我应该发布那个长错误消息吗? 提前谢谢。

3 个答案:

答案 0 :(得分:2)

  

我更像是一个java家伙。

以下是您需要了解的内容:

指针

Person*是指向某人的指针 - 指针只是携带内存中对象的地址。这是你能得到的低水平。它相当于在汇编语言中使用地址寄存器或索引寄存器。它不包含有关对象生命周期的信息,也不会以任何方式影响对象的生命周期。它是100%可滥用的。如果有的话,请小心使用。

共享参考

// java code
var x = new Y();
var y = x;

// equivalent c++
auto x = std::make_shared<Y>();
auto y = x;

如果你想要类似java的行为,那么std::shared_ptr<Person>等同于java对象引用。它共享该人的所有权并允许(实际上在c ++中强制执行)当所有shared_ptrs超出范围或已被重置时,Person被销毁。

具有生命周期控制的唯一引用

两者之间是一个std::unique_ptr<Person>,当唯一的unique_ptr被销毁或重置时,它将导致Person的自动销毁。您无法复制std::unique_ptr,因此无法用于共享对象的引用。但是,它可以转换为shared_ptr(这会隐式清空unique_ptr)。

弱引用

然后有一个std::weak_ptr<Person>,它是std::shared_ptr<Person>的弱对应物。它不能直接取消引用,但必须先使用shared_ptr方法转换为lock()。这为存在和锁定到位的操作提供了原子“测试”。我们使用它来解决或避免由循环引用引起的资源泄漏(java声称没有因垃圾回收而引起)。

Java和C ++之间的生命周期差异

在Java中,当对象没有更多可访问的引用时,它就成了垃圾收集的候选者。在未来的某个时刻,它可能会或可能不会被恢复。

C ++是不同的,更具可预测性。当重置控制对象生命周期的unique_ptr或最后shared_ptr时,该对象的析构函数将立即执行并在同一个线程中执行。这是完全顺序的。这就产生了RAII的可能性,并允许我们使用对象生存期来执行代码,无论执行路径是什么。

这也可以说是为什么c ++中不需要finally。资源清理是资源所有者的破坏者。

答案 1 :(得分:1)

您的代码看起来不错,除了一行:

students.insert(p -> getName(), p);

在这里,您可能意味着要将p放置到单元格p->getName(),但不幸的是,here没有将密钥和值作为两个参数的实例。将它们作为一个参数传递或使用operator[]应该有所帮助:

students[p->getName()] = p;
students.insert({p->getName(), p});
students.insert(std::make_pair(p->getName(), p));

如果可能,我个人会选择第一个选项,因为它更具可读性。

UP:正如@ Jarod42所评论的那样,这里的第一个选项要求值类型是默认的可构造的,这并不总是一个选项。

答案 2 :(得分:1)

int main()
{
  unordered_map<string, Person *> students;
  Student s("Sam", 26, "A");
  Person *p;
  p = &s;

  pair<string, Person*> item("key", p);
  students.insert(item);

  return 0;
}