【问题标题】:Initialization of a class object on C++ [duplicate]在 C++ 上初始化类对象 [重复]
【发布时间】:2023-03-17 14:50:01
【问题描述】:

我对如何在超类上没有默认构造函数的情况下进行对象初始化有疑问。

#include <iostream>

class A
{
protected:  
    A(std::string title, int xpos, int ypos);
};

class B : A
{
protected:
    //Is that correct?
    A* m_pA(std::string title, int xpos, int ypos); 
    //Why not just A* m_pA;? 
public:
    B(std::string title, int xpos, int ypos);
};

B::B(std::string title, int xpos, int ypos) : m_pA(title, xpos, ypos)
{
    //does nothing yet.     
}

如你所见,我试图在 B 的构造函数中初始化 A 类型的 m_pA 对象,VC 正在抛出我:

"m_pA" is not a nonstatic data member or base class of class "B"

您可以看到编译的示例和错误here

我想知道为什么以及如何在没有默认构造函数的情况下初始化一个类的成员对象,以及为什么我错了。

提前致谢!

【问题讨论】:

  • 你真的是要从A继承,并且有一个指向A的成员指针吗?无论如何,受保护的声明是一种方法。你仍然需要初始化基础
  • A* m_pA(std::string title, int xpos, int ypos); 是 B 类中的一个函数,返回指向 A 的指针。
  • 是的@sp2danny 你可能是对的,我的脑袋,只是太困惑了。 D:无论如何,如果我想要一个 A 类型的对象,我该如何初始化它?我只想调用 B 并且 A 将被初始化,这就是目标,问题可能不清楚......而 drescherjm 你是对的!
  • 因为,正如已经说过的 m_pA 不是非静态成员对象,试图在 ctor 初始化列表中对其进行初始化是错误的。无论如何,您想将参数传递给那里的A 基类子对象....(将列表中的m_pA 替换为A
  • 彻底摆脱 m_pA。将构造函数更改为B::B(std::string title, int xpos, int ypos) : A(title, xpos, ypos) {}

标签: c++ oop


【解决方案1】:

在构造子类时需要显式初始化基类。

B(std::string title, int xpos, int ypos)
    : A(title, xpos, ypos)
{}

您可能还应该通过 const 引用传递这些字符串,否则您将制作一堆不必要的副本。

【讨论】:

  • 至少解决所有问题...
  • @Aesthete 类似const std::string&amp; title?
  • @eRafaelNunes - 是的,这就是我所说的引用的意思。还要记住默认情况下继承是private,所以如果这不是你真正想要的,你必须像class B : public A一样继承。祝你好运!
【解决方案2】:

您的代码有一些错误。首先,要让继承的类访问受保护的变量/函数,继承的类必须是友元的。其次,您的私有变量 m_pA 是一个指针。不能像初始化 A 的实例一样初始化指向 A 的指针。看看这段代码:

#include <iostream>

class A
{
    friend class B;
protected:  
    A();
    A(std::string title, int xpos, int ypos);
};

A::A()
{
//Do something
}
A::A(std::string title, int xpos, int ypos)
{
//Do something
}

class B : A
{
protected:
    A* m_pA;    
public:
    B(std::string title, int xpos, int ypos);
};

B::B(std::string title, int xpos, int ypos)
{
    m_pA = new A(title, xpos, ypos);
}

int main() {

    return 0;
}

您可以在这里验证:http://ideone.com/gL1OxH

【讨论】:

  • 你的回答为我提供了一个灵活的 m_pA 初始化,这正是我所需要的,我试图完全按照你所做的,但是没有朋友类 B,我不知道:@987654323 @.
  • 很高兴我编码帮助。您还可以尝试删除“friend class B”,并将 B 的类声明更改为:'class B : protected A',总是不止一种方法可以给猫剥皮。
【解决方案3】:
class B : A
{
protected:
    A* p;
    A a;
public:
    B(std::string title, int xpos, int ypos)
         : A(title, xpos, ypos)          // init base
         , p(new A(title, xpos, ypos))   // init pointer
         , a(title, xpos, ypos)          // init member
    {}
};

【讨论】:

  • 特别是构造函数在调用基类构造函数之前初始化数据成员。更广泛地说,OP 的问题是,他认为他必须为基类提供数据成员,而实际上它隐含在派生类中。
  • @NicholasM:没有。每个标准的构建顺序:虚拟基地、其他基地、成员,按其定义的阅读顺序,而不是初始化列表的顺序。
  • 它旨在展示他可能想要的所有东西的用例
  • @drescherjm:请详细说明,有什么问题?
  • 我收回我的评论。必须更清楚地阅读答案,尤其是在观看体育比赛时..
猜你喜欢
  • 2015-12-03
  • 2013-07-23
  • 2012-01-17
  • 1970-01-01
  • 2016-02-09
  • 2016-02-26
  • 1970-01-01
  • 2011-10-09
  • 1970-01-01
相关资源
最近更新 更多