【问题标题】:c++ self in initialisation listc ++ self在初始化列表中
【发布时间】:2011-05-17 12:28:19
【问题描述】:

我有这个代码sn-p

class Osoba{
         Osoba(char* imie,int wiek){                         
                     this->imie=new char[strlen(imie)+1];
                     strcpy(this->imie,imie);
                     this->wiek=wiek;
                     cout<<"Utworzono Osobe "<<this->imie<<endl;
         }
         Osoba(Osoba& x){
                 Osoba(x.imie,x.wiek);
         }
[...]

当我调用复制构造函数时它不起作用(创建和销毁对象)。

编辑: 如果我使用

         Osoba(Osoba& x): Osoba(x.imie,x.wiek){

我收到type 'class Osoba' is not a direct base of 'Osoba'

这是怎么做到的?

【问题讨论】:

  • 在 C++ 中使用 std::string 而不是 char * 来表示字符串。它使事情变得简单得多。此外,您的标题暗示了一些关于初始化列表的内容,但您在显示的代码中没有使用任何内容。
  • @c0wb0y 我知道它只是用于教育目的 -> 为什么我使用 char*(动态内存分配等)

标签: c++ initialization-list


【解决方案1】:

你不能这样调用构造函数。好吧,你可以,但是会发生一个无名的临时对象被创建。在不引用其他构造函数的情况下编写您的复制构造函数。此外,如果您使用 std::string 而不是 char *,则不需要复制构造函数。如果你坚持使用 char *,你还需要一个析构函数和一个赋值运算符。

【讨论】:

  • 你 100% 确定你不能重用其他构造函数吗?是的,我有一个关于字符串的析构函数:)
  • @noob 您不能重用其他构造函数,但有时可以将代码分解为非构造函数私有成员函数。
  • @noob:别忘了正确定义复制构造函数:Osoba(const Osoba& x)
【解决方案2】:

你必须初始化Osoba的成员,就像你在另一个构造函数中所做的一样。

您只能在 C++2011 中重用构造函数(使用其他语法)。

【讨论】:

    【解决方案3】:

    除了创建另一个不同的对象之外,您不能调用构造函数。

    如果您需要在构造函数之间有一些共同的代码,您可以将它放在一个单独的方法中并调用该方法。请注意,在构造函数中您可以调用对象的方法,但virtual 方法不会调度派生类。

    换句话说,如果你有

    struct Foo
    {
        virtual void doit() { ... }
        Foo() {
            doit();
        }
    };
    
    struct Bar : Foo
    {
        virtual void doit() { ... }
    };
    

    Bar 的构造函数期间调用的doit 的实现将是在Foo 中定义的,因为在派生对象的基础部分的构造函数期间,该对象只是一个“基础”对象。只有在构造函数的末尾,它才会在“派生”构造函数中执行任何最终存在的代码之前成为“派生”对象。

    注意其他面向对象语言使用不同的方法...

    关于 C++ 中究竟发生了什么的解释see this article

    如果您喜欢合法的描述,这就是 C++ 标准 12.7.4 中的说明:

    成员函数,包括虚拟函数 函数(10.3),可以在期间调用 建造或破坏 (12.6.2)。 调用虚函数时 直接或间接地从 构造函数(包括从 数据成员的 mem-initializer) 或 从析构函数和对象 调用适用的是对象 在建造或破坏中, 调用的函数是定义在 构造函数或析构函数自己的 类或其基础之一,但不是 在类中覆盖它的函数 派生自构造函数或 析构函数的类,或覆盖它 在其他基类之一中 派生最多的对象(1.8)。如果 虚函数调用使用显式 类成员访问(5.2.5)和 object-expression 指的是对象 正在建设或破坏,但 它的类型既不是构造函数也不是 析构函数自己的类或其一个 基,调用的结果是 未定义。

    【讨论】:

    • 我会接受这个,因为它最有帮助:) 我喜欢快速而讨厌的黑客攻击。
    • 我认为“在 Bar 的构造函数期间调用的 doit 的实现将是 Foo 中定义的那个” 并不完全正确。标准是这样说的吗?是不是未指定/未定义?
    • @Nawaz:我在标准中找不到它,但 pdf 搜索很糟糕(而且搜索死树版本更加困难 ;-))。无论如何,我添加了一个链接,以解释确切的动态。我清楚地记得我在学习 C++ 时从权威来源读到过这个(但那是很多年前的事了,所以我不记得确切的来源......可能是 TCPPPL)。
    【解决方案4】:

    首先,构造函数不只是任何方法,你不能只将 at 用作 mutator 方法。

    也就是说, 我认为您的班级有两个领域,imie 和 wiek 是否正确?

    再次执行初始化代码,这次使用 x.imie 和 x.wiek 作为输入

    【讨论】:

      猜你喜欢
      • 2023-03-13
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多