Q1:如果A类引用B类,B类引用A类,如何解决调用的死循环?
例子:
//A的头文件 A.h
#include '"A.h"
class A{
private:
B b;
};
class A;//注意一:在B的头文件加上这个
class B{//注意二:不能再导入A的头文件
private:
A *a;//注意三:采用指针的方式引用A
}
//但A.cpp要 include"A.h"
Q2:定义静态成员函数?
Step1:在A.h的头文件定义类
class A{
public;
static bool fun();
}
Step2:在A.cpp的文件实现这个静态方法
#include “A.h”
bool A::fun(){//注意一:此处是不需要static 修饰
}
Q3JAVA有空对象只说,可以返回NULL代表空对象,在C++里如何处理?
AbstractEntity AbstractEntity::findEntityById(QString idname){
if((getId()!=NULL)&&(getId()==idname))
return this;
return NULL;//本来想返回空对象的但C++ NULL只代表 int 0,会提示返回类型格式不正确
}
修改:
AbstractEntity * AbstractEntity::findEntityById(QString idname){//Step:定义返回指向一个对象的指针
if((getId()!=NULL)&&(getId()==idname))
return this;
return NULL;
}
Q3:子类如何使用父类的构造方法?
例子:其中 AbstractEntity是NamedEntity父类
NamedEntity::NamedEntity(QString id, QString name):AbstractEntity(id){//
this->name=name;
}
Q4:如果同一个类中使用了子类和父类头文件应该如何包含?
Q5:如何用生成对象?
case1:
A *a=new A();//定义一个指向对象的指针变量
或者有参的构造函数
A *a=new A(a,b);
case2:
A a;//定义一个对象
Q6:子类要使用父类的方法?
其中:AbstractEntity 为父类 NamedEntity为子类 都有一个check()方法,但我要使用父类的check()方法
例子
QList<NetError *> NamedEntity::check(){
QList<NetError *> errors=AbstractEntity::check();//调用父类的方法
return errors;
}
Q7:父类中如果要使用子类对象,如何解决?
分析
1.子类继承父类,则子类要包含父类的头文件,然而父类要使用子类则要包含子类的头文件,则产生相互包含的问题
例子:
//Parent.h
class Children;//声明你要使用子类,但是不能用include的方式
class Parent{
public:
void fun(Children *child);
}
Parent.cpp
#include "Parenth"
#include "Children.h"//注意父类的cpp里面要申明调用了子类头文件
#include "Parent.h"
class Children : public Parent{
public:
}
Q7:QT编程时出现错误代码: -1073741819 cmd命令窗口闪退
例子:
错误前:
QDomElement SCPNET::getUnieqSubElement(QDomElement e,QString nodeName){//定义的返回类型是一个对象
QString elemName = e.nodeName();
if(!e.isNull()){
QDomNodeList list=e.childNodes();//获得下面所有的子节点
qDebug()<<"List Count"<<list.count();
for(int i=0;i<list.count();i++){
QDomNode node=list.at(i);
if(node.nodeName()==nodeName){
qDebug()<<"node name is"<<node.nodeName();
qDebug()<<"node type is"<<node.nodeType();
QDomElement elem=node.toElement();
return elem;
}
}
}
错误后:
QDomElement* SCPNET::getUnieqSubElement(QDomElement e,QString nodeName){//修改后返回的是一个指针
QString elemName = e.nodeName();
if(!e.isNull()){
QDomNodeList list=e.childNodes();//获得下面所有的子节点
qDebug()<<"List Count"<<list.count();
for(int i=0;i<list.count();i++){
QDomNode node=list.at(i);
if(node.nodeName()==nodeName){
qDebug()<<"node name is"<<node.nodeName();
qDebug()<<"node type is"<<node.nodeType();
QDomElement elem=node.toElement();
return &elem;
}
}
}
问题分析:
查资料:内存管理的问题
程序里面申请的堆区的空间太多,把用new申请的空间转变为申请栈区的局部变量。
扩展:
如何分配堆和栈的内存及如何进行内存的管理
Q8:错误信息: SCPNTimedTransition.h|2|error: macro names must be identifiers|?
宏名必须是标识符
错误之前:
#ifndef "TIMETRAN_H"
#define "TIMETRAN_H"
标识符只能是字母下划线及数字(数字不可开头)
改为:
#ifndef "TIMETRAN_H"
#define "TIMETRAN_H"
Q8:codeblocks 开发错误集。1.undefined reference to `SCPNTimedTransition::SCPNTimedTransition(QString, QString)'|
分析:我的类SCPNTimedTransition 不仅定义而且构造方法都实现了,但是说找不到,我测试了无参和有参的构造方法,均出现同样的错误,因此可能是
.pro文件没有将SCPNTimedTransition.cpp文件名写入文件,添加上即可
2.error: invalid use of 'this' in non-member function|
z在非类的成员里使用this指针
错误前
SCPNTimeFunction getTimeFunction(){//此处要加类名修饰
return this->timeFunction;
}
分析:自己掉了类名修饰符,所以不是类的成员函数
SCPNTimeFunction SCPNTimedTransition::getTimeFunction(){
return this->timeFunction;
}
Q9:SCPNET.h|42|error: 'SCPNRecordTokenType' was not declared in this scope说这个类在这个范围内没有定义?
Q10:在fun1 中定义一个指向字符串对象的指针,通过在fun2中给所指字符串赋值,带回字符串的值。
void fun1()
{
QString *s1;
fun2(s1);
}
void fun2(QString *str)
{
str=new QString();
}
错误分析;在fun1中只是定义指向字符串对象的指针变量,而该指针变量根本没有赋值,当通过调用fun2,只是通过值传递,把一个值传给fun2的函数参数为指针变量,然后fun2的str指针变量赋值后,对原来的s1指针没有影响。
修改:
void fun1()
{
<del>QString *s1;</del>
QString *str1=new QStiring();
fun2(s1);
}
void fun2(QString *str)
{
<del>str=new QString();</del>
......
}
先给指针变量赋值(new 的方式开辟对象空间),然后指针变量作为参数传递,修改该对象的值
Q11:复制构造函数
class A{
QList<Attribute *> attributes;
A(A *a)
<span style="font-family: Arial, Helvetica, sans-serif;">{</span>
<span style="white-space:pre"> </span>this->name=a->name();
<span style="white-space:pre"> </span>this->attributes=a->attributes;
}
}
分析:
本来直接将一个QList的值赋值给另一个QList是可以的,但QList存放的是指针,只是复制指针的值,但是指针所指的对象就是一个,没有复制过来
修改
A(A *a)
{
this->name=a->name;
for(int i=0;i<attribues->size();i++)
{
Attribute *attr=new Attribute();//产生新的对象,当然对象的一些属性也要赋值
this->attributes.append(attr);
}
}
Q12:QVctor 内存空间的释放?
A::~A()//类A的析构函数
{
for(QList<SCPNAttribute *>::iterator it=this->attributes.begin();it!=this->attributes.end();it++)
{
if(NULL!=*it)
{
delete *it;
*it=NULL;
}
}
this->attributes.clear();
}
说明我在A中定义了 成员变量 QList<SCPNAttribute *> attributes;并在一个函数用new 的方式产生 SCPNAttribute,并append.
Q13:c++生成随机数?
#include <stdlib.h>
#include <time.h>
//产生0-N-1之间的随机数
int getRandom(int N)
{
srand((unsigned)time(NULL));//根据时间而改变
//1、如果N<RAND_MAX+1,则要去除尾数
int R = RAND_MAX-(RAND_MAX+1)%N; //去除尾数
int t = rand();
while(t>R) t = rand();
int result = t % N; // 符合要求的随机数
return result;
}
#include <iostream>
cout<<__FILE__<<__LINE__<<__func__<<endl;
Q15:在一个类中定义枚举类型,并使用
class A{
public:
enum Ttype//若在后面使用到枚举类型,必须在使用前申明
{
TYPEA,
TYPEB,
TYPEC
};
private:
Ttype var;//定义一个枚举类型的变量
void set(Type type);
Ttype get();
};
#include "A.h"
A::Ttype get() <span style="font-family: Arial, Helvetica, sans-serif;">//注意这里必须申明在A类型下定义了枚举,否则出错,说Ttype未定义</span>
{
return this->var;
<span style="font-family: Arial, Helvetica, sans-serif;">}</span>
<span style="font-family: Arial, Helvetica, sans-serif;">void set(Ttype type)//为什么这边不用申明?</span>
<span style="font-family:Arial, Helvetica, sans-serif;">{</span>
<span style="font-family:Arial, Helvetica, sans-serif;"><span style="white-space:pre"> </span>this->var=type;</span>
<span style="font-family:Arial, Helvetica, sans-serif;">}</span>
<span style="font-family:Arial, Helvetica, sans-serif;">//使用</span>
<span style="font-family:Arial, Helvetica, sans-serif;">A *a=new A();</span>
<span style="font-family:Arial, Helvetica, sans-serif;">a->set(Ttype::TYPEA);</span>
Q15:关于拷贝构造函数?
SCPNRecordTokenType *ltoken=leftPlace->getMarking()->getTokenInstancs().at(i);//测试结果为0,但是我已经在之前进行了初始化
SCPNMarking marking;//定义一个类的成员为SCPNMarking类型对象,调用默认的构造函数进行初始化
fun()
{
marking=SCPNMarking(this->initialMarkingStr);//此处调用SCPNMarking的默认浅拷贝构造函数
<span style="font-family: Arial, Helvetica, sans-serif;">marking->prepare(tokenType);</span>
}
问题分析:我没有重写=操作符,调用默认的=操作符函数,又因为SCPNMarking 有指针成员,只进行浅拷贝,当=右侧的对象,在函数结束时销毁,内存被释放。
问题2:我并没有去delete 通过new 方式开辟的内存空间 那段内存存放的内容应该还存在
解决方案-:
SCPNMarking *marking;
fun()
{
marking=new SCPNMarking(this->initialMarkingStr);//需要定义拷贝构造函数吗?问题,调用默认的构造函数,函数结束时,对象消失
marking->prepare(tokenType);
}
解决方案二:重载=操作符函数
Q16:编译器提示错误:A undefined reference to `A::A()'|
问题分析:此类之前编译没有出错,自从增加了A类 ,并且B类有A类的成员对象,错误指示在B类的构造函数
解决:A类定义了有参的构造函数,而B类的A类成员变量,在类中是默认初始化的调用A类的默认无参构造函数,因此添加A类的无参构造函数即可