我在一个项目里的一个B类声明中创建了A类的对象,使用A类的有参构造。被B类误认为是函数声明。此错误困扰了我很长时间,现在将错误复盘如下:

错误描述

#include <iostream>
#include <string>

using namespace std;

class classA
{
public:
    classA(int i);
};

classA::classA(int i)
{
    cout << i << "by classA" << endl;
}

class classB
{
public:
    classB(int j);
    classA a(1);
};

classB::classB(int j) 
{
    cout << j << "by classB" << endl;
}

int main()
{
    classB b(1);//声明一个对象
    system("pause");
    return 0;
}

这时候,会报错:

2    IntelliSense:  应输入类型说明符    e:\WorkSpace\C&C++\Error\类内声明另一个类对象\类内声明另一个类对象\err.cpp    21    11    类内声明另一个类对象
1    error C2059: 语法错误:“常量”    e:\workspace\c&c++\error\类内声明另一个类对象\类内声明另一个类对象\err.cpp    21    1    类内声明另一个类对象

错误分析

看这句话

class classB
{
...

    classA a(1);
...
};

编译器把classA a(1);当做是函数的声明。其中classA是函数返回值,a是函数名,而(1)不是符合形参格式。
如果不理解可以看下面的文章
必须使用【初始化列表】初始化数据成员的情况

解决方案

方案一:使用初始化列表

#include <iostream>
#include <string>

using namespace std;

class classA
{
public:
    classA(int i);
};

classA::classA(int i)
{
    cout << i << "by classA" << endl;
}

class classB
{
public:
    classB(int j);
    classA a;
    classA a1;
};

classB::classB(int j) : a(0) , a1(1)
{
    cout << j << "by classB" << endl;
}

int main()
{
    classB b(1);//声明一个对象
    system("pause");
    return 0;
}

其中

...
classB::classB(int j) : a(0) , a1(1)
...

就是使用了初始化列表的方式,个人认为是使用构造函数时在创建classB对象时,给声明的classA对象赋值

方案二:不要声明类对象,声明一个类指针

#include <iostream>
#include <string>

using namespace std;

class classA
{
public:
    classA(int i);
};

classA::classA(int i)
{
    cout << i << "by classA" << endl;
}

class classB
{
public:
    classB(int j);
    ~classB();//创建析构函数,删除构造函数中new的对象
    classA * a;
    classA * a1;
};

classB::classB(int j)
{
    a = new classA(0);
    a1 = new classA(1);
    cout << j << "by classB" << endl;
}

classB::~classB()
{
    delete a;//删除a对象
    a = NULL;//给对象指针重新指向NULL,防止野指针
    delete a1;
    a1 = NULL;
}

int main()
{
    classB b(1);//声明一个对象
    system("pause");
    return 0;
}
  • 千万记得要在析构函数中删除创建的对象

展望

还是不是很理解,方案一中classB的声明中,为何可以直接classA a;,是调用的默认构造函数吗?我猜不是,但是是什么呢?
待以后研究吧...
干活了...
写于上班中
-2022年5月13日10:23:48