第2章:課題の実装
はじめに
本章では、CPP Module 01の各演習を実装します。
---
1. ex00: BraiiiiiiinnnzzzZ
1.1 課題の要件
- Zombieクラスを作成
- スタックとヒープでのオブジェクト生成を比較
newZombie関数でヒープに生成randomChump関数でスタックに生成
1.2 実装
// Zombie.hpp
#ifndef ZOMBIE_HPP
#define ZOMBIE_HPP
#include <string>
class Zombie {
private:
std::string _name;
public:
Zombie();
Zombie(const std::string& name);
~Zombie();
void announce() const;
};
Zombie* newZombie(std::string name);
void randomChump(std::string name);
#endif
// Zombie.cpp
#include "Zombie.hpp"
#include <iostream>
Zombie::Zombie() : _name("Unnamed") {}
Zombie::Zombie(const std::string& name) : _name(name) {}
Zombie::~Zombie() {
std::cout << _name << " is destroyed" << std::endl;
}
void Zombie::announce() const {
std::cout << _name << ": BraiiiiiiinnnzzzZ..." << std::endl;
}
// newZombie.cpp
#include "Zombie.hpp"
Zombie* newZombie(std::string name) {
return new Zombie(name);
}
// randomChump.cpp
#include "Zombie.hpp"
void randomChump(std::string name) {
Zombie zombie(name);
zombie.announce();
}
// main.cpp
#include "Zombie.hpp"
int main() {
// ヒープに生成
Zombie* heapZombie = newZombie("HeapZombie");
heapZombie->announce();
// スタックに生成
randomChump("StackZombie");
// ヒープのゾンビを削除
delete heapZombie;
return 0;
}
---
2. ex01: Moar brainz!
2.1 課題の要件
zombieHorde関数で配列を返す2.2 実装
// Zombie.hpp
#ifndef ZOMBIE_HPP
#define ZOMBIE_HPP
#include <string>
class Zombie {
private:
std::string _name;
public:
Zombie();
~Zombie();
void setName(const std::string& name);
void announce() const;
};
Zombie* zombieHorde(int N, std::string name);
#endif
// zombieHorde.cpp
#include "Zombie.hpp"
Zombie* zombieHorde(int N, std::string name) {
if (N <= 0)
return NULL;
Zombie* horde = new Zombie[N];
for (int i = 0; i < N; i++) {
horde[i].setName(name);
}
return horde;
}
// main.cpp
#include "Zombie.hpp"
int main() {
int N = 5;
Zombie* horde = zombieHorde(N, "Zombie");
for (int i = 0; i < N; i++) {
horde[i].announce();
}
delete[] horde;
return 0;
}
---
3. ex02: HI THIS IS BRAIN
3.1 課題の要件
3.2 実装
#include <iostream>
#include <string>
int main() {
std::string str = "HI THIS IS BRAIN";
std::string* stringPTR = &str;
std::string& stringREF = str;
std::cout << "Address of str: " << &str << std::endl;
std::cout << "Address of stringPTR: " << stringPTR << std::endl;
std::cout << "Address of stringREF: " << &stringREF << std::endl;
std::cout << "Value of str: " << str << std::endl;
std::cout << "Value of stringPTR: " << *stringPTR << std::endl;
std::cout << "Value of stringREF: " << stringREF << std::endl;
return 0;
}
---
4. ex03: Unnecessary violence
4.1 課題の要件
4.2 実装
// Weapon.hpp
#ifndef WEAPON_HPP
#define WEAPON_HPP
#include <string>
class Weapon {
private:
std::string _type;
public:
Weapon(const std::string& type);
const std::string& getType() const;
void setType(const std::string& type);
};
#endif
// HumanA.hpp
#ifndef HUMANA_HPP
#define HUMANA_HPP
#include "Weapon.hpp"
#include <string>
class HumanA {
private:
std::string _name;
Weapon& _weapon; // 参照:常に武器を持つ
public:
HumanA(const std::string& name, Weapon& weapon);
void attack() const;
};
#endif
// HumanB.hpp
#ifndef HUMANB_HPP
#define HUMANB_HPP
#include "Weapon.hpp"
#include <string>
class HumanB {
private:
std::string _name;
Weapon* _weapon; // ポインタ:武器を持たない可能性
public:
HumanB(const std::string& name);
void setWeapon(Weapon& weapon);
void attack() const;
};
#endif
// HumanA.cpp
#include "HumanA.hpp"
#include <iostream>
HumanA::HumanA(const std::string& name, Weapon& weapon)
: _name(name), _weapon(weapon) {}
void HumanA::attack() const {
std::cout << _name << " attacks with their " << _weapon.getType() << std::endl;
}
// HumanB.cpp
#include "HumanB.hpp"
#include <iostream>
HumanB::HumanB(const std::string& name) : _name(name), _weapon(NULL) {}
void HumanB::setWeapon(Weapon& weapon) {
_weapon = &weapon;
}
void HumanB::attack() const {
if (_weapon) {
std::cout << _name << " attacks with their " << _weapon->getType() << std::endl;
} else {
std::cout << _name << " has no weapon" << std::endl;
}
}
---
5. ex04: Sed is for losers
5.1 課題の要件
std::string::replaceは使用禁止5.2 実装
#include <iostream>
#include <fstream>
#include <string>
std::string replaceAll(const std::string& content,
const std::string& s1,
const std::string& s2) {
std::string result;
size_t pos = 0;
size_t prevPos = 0;
while ((pos = content.find(s1, prevPos)) != std::string::npos) {
result += content.substr(prevPos, pos - prevPos);
result += s2;
prevPos = pos + s1.length();
}
result += content.substr(prevPos);
return result;
}
int main(int argc, char** argv) {
if (argc != 4) {
std::cerr << "Usage: " << argv[0] << " <filename> <s1> <s2>" << std::endl;
return 1;
}
std::string filename = argv[1];
std::string s1 = argv[2];
std::string s2 = argv[3];
if (s1.empty()) {
std::cerr << "Error: s1 cannot be empty" << std::endl;
return 1;
}
std::ifstream inFile(filename.c_str());
if (!inFile) {
std::cerr << "Error: Cannot open file" << std::endl;
return 1;
}
std::string content;
std::string line;
while (std::getline(inFile, line)) {
if (!content.empty())
content += '\n';
content += line;
}
inFile.close();
std::string replaced = replaceAll(content, s1, s2);
std::ofstream outFile((filename + ".replace").c_str());
if (!outFile) {
std::cerr << "Error: Cannot create output file" << std::endl;
return 1;
}
outFile << replaced;
outFile.close();
return 0;
}
---
6. ex05: Harl 2.0
6.1 課題の要件
6.2 実装
// Harl.hpp
#ifndef HARL_HPP
#define HARL_HPP
#include <string>
class Harl {
private:
void debug();
void info();
void warning();
void error();
public:
void complain(std::string level);
};
#endif
// Harl.cpp
#include "Harl.hpp"
#include <iostream>
void Harl::debug() {
std::cout << "[ DEBUG ]" << std::endl;
std::cout << "I love having extra bacon..." << std::endl;
}
void Harl::info() {
std::cout << "[ INFO ]" << std::endl;
std::cout << "I cannot believe adding extra bacon costs more money..." << std::endl;
}
void Harl::warning() {
std::cout << "[ WARNING ]" << std::endl;
std::cout << "I think I deserve to have some extra bacon for free..." << std::endl;
}
void Harl::error() {
std::cout << "[ ERROR ]" << std::endl;
std::cout << "This is unacceptable! I want to speak to the manager now." << std::endl;
}
void Harl::complain(std::string level) {
void (Harl::*functions[4])() = {
&Harl::debug,
&Harl::info,
&Harl::warning,
&Harl::error
};
std::string levels[4] = {"DEBUG", "INFO", "WARNING", "ERROR"};
for (int i = 0; i < 4; i++) {
if (levels[i] == level) {
(this->*functions[i])();
return;
}
}
std::cout << "Unknown level: " << level << std::endl;
}
---
7. ex06: Harl filter
7.1 課題の要件
7.2 実装
// harlFilter.cpp
#include "Harl.hpp"
#include <iostream>
int main(int argc, char** argv) {
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << " <level>" << std::endl;
return 1;
}
Harl harl;
std::string level = argv[1];
int levelIndex = -1;
if (level == "DEBUG") levelIndex = 0;
else if (level == "INFO") levelIndex = 1;
else if (level == "WARNING") levelIndex = 2;
else if (level == "ERROR") levelIndex = 3;
switch (levelIndex) {
case 0:
harl.debug();
// fall through
case 1:
harl.info();
// fall through
case 2:
harl.warning();
// fall through
case 3:
harl.error();
break;
default:
std::cout << "[ Probably complaining about insignificant problems ]" << std::endl;
}
return 0;
}
---
まとめ
本章で実装した内容: