C++编程出现的问题

本文探讨了C++编程中的常见问题,包括解决类间引用导致的死循环、空对象处理、子类构造方法调用、内存管理和随机数生成等,并提供了详细的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
}


Q14:C++调试?

#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类的无参构造函数即可




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值