如何访问基类的公共数据成员

How to access public data member of base class?

本文关键字:数据成员 基类 何访问 访问      更新时间:2023-10-16

如何访问派生类中的基类数据成员?我想使用已在subMenuLists::changeWidget()中初始化customizeCSMWindow()构造函数的docElem数据成员。

class myWidget
{
public :
QDomElement docElem; 
QDomDocument *menuOrderXMLFile;
};
class subMenuLists : public QListWidget , public myWidget
{
Q_OBJECT
public slots:
void changeWidget( int index);
};
class customizeCSMwindow : public QDialog , public myWidget
{
Q_OBJECT
public :
subMenuLists *menuList;
customizeCSMwindow(QString);       
}
customizeCSMwindow::customizeCSMwindow(QString fileName)
{
menuOrderXMLFile = new QDomDocument();
file = new QFile(fileName);
QString errorStr;
int errorLine;
int errorColumn;
if(!menuOrderXMLFile->setContent(file, false , &errorStr, &errorLine,
&errorColumn))
std::cout<<"not found n";
else
docElem = menuOrderXMLFile->documentElement();
}
void subMenuLists::changeWidget(int index)
{
clear();
// How to access that docElem here??
}

如何访问void subMenuLists::changeWidget()功能中的docElem

编辑

我想解释一下我的问题,看看你能不能帮我。我想要的是,在subMenuList::changeWidget()函数中,得到在cusomizeCSMWidnow构造器中分配的docElem的值。到目前为止,当我在changeWidget函数中访问docElem时,它给出了null/未初始化的值。

customizeCSMwindow类似于subMenuLists类型元素的容器。容器和元素各自具有成员CCD_ 13。您尝试在subMenuLists中访问容器customizeCSMwindow的成员docElem

这不能直接奏效。要么给容器的元素一个指向容器的指针,要么在subMenuLists::changeWidget的调用中给容器的指针。

解释元素中指向容器的指针的示例:

#include <string>
#include <iostream>
class myWidget
{
public :
std::string docElem;
};
class customizeCSMwindow;
class subMenuLists : public myWidget
{
customizeCSMwindow* m_pContainer; // Pointer to the container
public:
subMenuLists(customizeCSMwindow* pContainer) :
m_pContainer(pContainer)
{}
void changeWidget(int index);
};
class customizeCSMwindow : public myWidget
{
public:
subMenuLists *menuList; // This pointer makes customizeCSMwindow to a container.
customizeCSMwindow();
void setMenuList(subMenuLists* ml) {
menuList = ml;
}
};
customizeCSMwindow::customizeCSMwindow() // Here we set docElem of the **container**.
{
docElem = " docElem in customizeCSMwindow";
}
void subMenuLists::changeWidget(int index) // In the **element** we want to access the  docElem of the **container**
{
// How to access that docElem here??
std::cout << "nIn changeWidget:" << m_pContainer->docElem << "n";
}
int main() {
customizeCSMwindow job;
subMenuLists menu(&job);
job.setMenuList(&menu);
menu.changeWidget(0);
}

在评论中,你问:"还有一件事,这个设计看起来不错吗?或者你能建议一种更好的方法,让同一个变量,即在两个不同的类中访问docElem吗?">

这在很大程度上取决于目标。如果menuList中可能有多个元素,则应避免使用原始指针。您应该使用std::shared_ptrstd::vector。如果这只是某种指针实现pimpl(请参阅Scott Meyers的有效c++),那么原始指针就可以了。

关于好的实现有太多的话要说。你需要阅读有关这方面的书籍(例如,标准书籍[Stroustrup:C++]或[Scott Meyers:Effective C++],或者你可以在讨论中通过谷歌轻松找到的好的参考资料)。

对于CCD_ 21中的多个元素,下面只有一种可能的实现方式。

#include <string>
#include <iostream>
#include <stdexcept> // for std::out_of_range
#include <memory> // for std::shared_ptr
#include <vector>
class myWidget
{
public :
std::string docElem;
};
class customizeCSMwindow;
class subMenuLists : public myWidget
{
customizeCSMwindow* m_pContainer; // Pointer to the container
/* The private constructor only allows the friend customizeCSMwindow to
construct elements of subMenuLists. This makes sure that pContainer is right. */
subMenuLists(customizeCSMwindow* pContainer) :
m_pContainer(pContainer)
{}
public:
void changeWidget(int index);
friend customizeCSMwindow;
};
class customizeCSMwindow : public myWidget
{
/* shared_ptr takes care of the deletion of allocated memory for subMenuLists. */
typedef std::shared_ptr<subMenuLists> pSubMenuLists_t;
/* Automatically runs the destructors of the elements when menuList is destructed. */
std::vector<pSubMenuLists_t> menuList; // This pointer makes customizeCSMwindow to a container.
public:
customizeCSMwindow();
/* The only and right way to generate new MenuLists. Takes care of the right m_pContainer. */
void addMenuLists(/*Stuff needed for the construction of an element of type subMenuLists*/) {
pSubMenuLists_t ml(new subMenuLists(this /* stuff for subMenuLists */));
menuList.push_back(ml);
}
/* One possible interface to make iteration over menuList possible. (There are other ways too.) */
size_t sizeMenuList() {
return menuList.size();
}
subMenuLists* getMenuListItem(size_t i) throw(std::out_of_range)
{
return menuList.at(i).get(); 
}
};
customizeCSMwindow::customizeCSMwindow() // Here we set docElem of the **container**.
{
docElem = " docElem in customizeCSMwindow";
}    
void subMenuLists::changeWidget(int index) // In the **element** we want to access the  docElem of the **container**
{
// How to access that docElem here??
std::cout << "nIn changeWidget:" << m_pContainer->docElem << "n";
}
int main() {
size_t i;
customizeCSMwindow job;
job.addMenuLists();
for(i=0; i!=job.sizeMenuList(); i++)
job.getMenuListItem(i)->changeWidget(0);
return 0;
}
/*
Local Variables:
compile-command: "g++ -std=c++11 test3.cc -o a.exe; ./a.exe"
End:
*/

派生类可以访问父级的公共成员和受保护成员。您只需使用docElem,就好像它是subMenuLists的成员一样。

继承的主要目的是使基类中的公共(和受保护的)数据和函数对派生类可用,就好像这些数据和函数是在派生类本身中声明的一样。

例如:

class BASE {
public:
int baseData; //the data you want to use
void workOnBaseData(){
baseData = 5;
}
}; 
class DERIVED : public BASE {
public:
int someData; //data member of the derived class
void workOnBaseAndSomeData(){
someData = baseData; //baseData is already known to DERIVED via inheritance
}
};

执行完这段代码后,会发现someData=5!希望这能有所帮助。

相关文章: