鱼C论坛

 找回密码
 立即注册
查看: 104|回复: 3

[已解决]c++友元函数初学习

[复制链接]
发表于 昨天 20:43 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
Compute类
#pragma once
#include "string"
#include "ComputerService.h"

using namespace std;

class ComputerService;
class Compute
{
public:
        Compute();
        string description();

private:
        string cpu;
        friend void ComputerService::upgrade(Compute* compute);
};

*****************
#include "Compute.h"
#include <sstream>
#include "ComputerService.h"

Compute::Compute()
{
        this->cpu = "i7";
}

string Compute::description()
{
        stringstream ret;
        ret << "CPU = " << cpu;
        return ret.str();
}

ComputerService类
#pragma once
#include "Compute.h"
class Compute;
class ComputerService
{
public:
        ComputerService();
        void upgrade(Compute* compute);
};
*******************************
#include "ComputerService.h"
#include "Compute.h"

ComputerService::ComputerService()
{
}

void ComputerService::upgrade(Compute* compute)
{
        compute->cpu = "i9";
}

主函数
#include <iostream>
#include "string"
#include<Windows.h>
#include <fstream>
#include  <sstream>
#include "Compute.h"
#include "ComputerService.h"
using namespace std;


int main(void) {
        Compute compute;
        ComputerService service;
        cout << compute.description() << endl;

        service.upgrade(&compute);

        cout << compute.description() << endl;


        system("pause");
        return 0;
}

报错显示
捕获.JPG
最佳答案
昨天 21:01
猪猪虾 发表于 2024-09-24 21:01
为什么我的程序报错显示,使用了未定义类型“Computer ...


鱼油你好,根据你的描述,我发现问题可能和友元函数的声明及包含关系有关。这一般是由于前向声明导致的问题,因为编译器在处理 `ComputerService::upgrade` 函数时未找到其定义。我们需要处理头文件包含的先后顺序。

下面是经过修改后可行的代码示例:

### Compute.h
#pragma once
#include <string>

using namespace std;

class ComputerService;

class Compute {
public:
    Compute();
    string description();

private:
    string cpu;
    friend class ComputerService; // 声明为友元类即可,无需特定函数
};

### Compute.cpp
#include "Compute.h"
#include <sstream> // 包含 sstream 头文件
#include "ComputerService.h"

Compute::Compute() {
    this->cpu = "i7";  // 构造函数初始化 cpu 为 "i7"
}

string Compute::description() {
    stringstream ret;
    ret << "CPU: " << cpu;
    return ret.str();
}

### ComputerService.h
#pragma once
#include "Compute.h"

class Compute;

class ComputerService {
public:
    void upgrade(Compute* compute);
};

### ComputerService.cpp
#include "ComputerService.h"
#include "Compute.h"

void ComputerService::upgrade(Compute* compute) {
    // 可以访问 Compute 类的私有成员
    compute->cpu = "i9";
}

### main.cpp
#include <iostream>
#include "Compute.h"
#include "ComputerService.h"

using namespace std;

int main() {
    Compute myComputer;
    ComputerService service;
    
    cout << "Before upgrade: " << myComputer.description() << endl;
    service.upgrade(&myComputer);
    cout << "After upgrade: " << myComputer.description() << endl;

    return 0;
}

### 说明:
1. `Compute.h` 中声明整个 `ComputerService` 类为友元。
2. `Compute.cpp` 和 `ComputerService.cpp` 各自在合适的地方包含对应的头文件。
3. 使用 `main.cpp` 测试代码。

这样修改后,你的程序应该不会再出现未定义类型的错误啦。希望这能帮到你!如果还有问题,请随时问我。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 昨天 20:50 | 显示全部楼层
鱼油你好,关于你的代码问题,似乎你想了解如何使用友元函数。在 C++ 中,友元函数是可以访问类的私有成员的函数。以下是对你提供的代码进行完善的一种方式:

### Compute 类定义(Compute.h)
#pragma once
#include "string"
#include "ComputerService.h"

using namespace std;

class ComputerService;

class Compute {
public:
    Compute();
    string description();

private:
    string cpu;
    friend void ComputerService::upgrade(Compute* compute);
};

### Compute 类实现(Compute.cpp)
#include "Compute.h"
#include <sstream> // 需要包含 sstream 头文件
#include "ComputerService.h"

Compute::Compute() {
    this->cpu = "i7";  // 构造函数初始化 cpu 为 "i7"
}

string Compute::description() {
    stringstream ret;
    ret << "CPU: " << cpu;
    return ret.str();
}

### ComputerService 类定义(ComputerService.h)
#pragma once
#include "Compute.h"

class ComputerService {
public:
    void upgrade(Compute* compute);
};

### ComputerService 类实现(ComputerService.cpp)
#include "ComputerService.h"

void ComputerService::upgrade(Compute* compute) {
    if (compute) {
        compute->cpu = "i9";  // 升级 CPU
    }
}

### 主函数(main.cpp)
#include <iostream>
#include "Compute.h"
#include "ComputerService.h"

int main() {
    Compute myComputer;
    ComputerService service;

    std::cout << "Before upgrade: " << myComputer.description() << std::endl;

    service.upgrade(&myComputer);

    std::cout << "After upgrade: " << myComputer.description() << std::endl;

    return 0;
}

### 编译与执行
确保所有文件放在同一个项目目录下并编译运行。你将看到类似如下输出:
Before upgrade: CPU: i7
After upgrade: CPU: i9

希望这些解释和代码改进能帮你理解 C++ 中的友元函数用法!如果有其他问题,欢迎继续提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 21:01 | 显示全部楼层
FishC 发表于 2024-9-24 20:50
鱼油你好,关于你的代码问题,似乎你想了解如何使用友元函数。在 C++ 中,友元函数是可以访问类的私有成员 ...

为什么我的程序报错显示,使用了未定义类型“ComputerService”        Project1        I:\c及C++练习及混编,GPU加速-23-6-15\Project1\Compute.h        17       
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 21:01 | 显示全部楼层    本楼为最佳答案   
猪猪虾 发表于 2024-09-24 21:01
为什么我的程序报错显示,使用了未定义类型“Computer ...


鱼油你好,根据你的描述,我发现问题可能和友元函数的声明及包含关系有关。这一般是由于前向声明导致的问题,因为编译器在处理 `ComputerService::upgrade` 函数时未找到其定义。我们需要处理头文件包含的先后顺序。

下面是经过修改后可行的代码示例:

### Compute.h
#pragma once
#include <string>

using namespace std;

class ComputerService;

class Compute {
public:
    Compute();
    string description();

private:
    string cpu;
    friend class ComputerService; // 声明为友元类即可,无需特定函数
};

### Compute.cpp
#include "Compute.h"
#include <sstream> // 包含 sstream 头文件
#include "ComputerService.h"

Compute::Compute() {
    this->cpu = "i7";  // 构造函数初始化 cpu 为 "i7"
}

string Compute::description() {
    stringstream ret;
    ret << "CPU: " << cpu;
    return ret.str();
}

### ComputerService.h
#pragma once
#include "Compute.h"

class Compute;

class ComputerService {
public:
    void upgrade(Compute* compute);
};

### ComputerService.cpp
#include "ComputerService.h"
#include "Compute.h"

void ComputerService::upgrade(Compute* compute) {
    // 可以访问 Compute 类的私有成员
    compute->cpu = "i9";
}

### main.cpp
#include <iostream>
#include "Compute.h"
#include "ComputerService.h"

using namespace std;

int main() {
    Compute myComputer;
    ComputerService service;
    
    cout << "Before upgrade: " << myComputer.description() << endl;
    service.upgrade(&myComputer);
    cout << "After upgrade: " << myComputer.description() << endl;

    return 0;
}

### 说明:
1. `Compute.h` 中声明整个 `ComputerService` 类为友元。
2. `Compute.cpp` 和 `ComputerService.cpp` 各自在合适的地方包含对应的头文件。
3. 使用 `main.cpp` 测试代码。

这样修改后,你的程序应该不会再出现未定义类型的错误啦。希望这能帮到你!如果还有问题,请随时问我。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-25 21:31

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表