diff --git a/animals/animal.cpp b/animals/animal.cpp index 6745215..5c4d7f5 100644 --- a/animals/animal.cpp +++ b/animals/animal.cpp @@ -1,7 +1,153 @@ #include "animal.h" -using namespace std; +Animal::Animal() : _massInKilos(20) +{ +} -int main() { - return 0; +void Animal::setMass(const float& newMass) +{ + _massInKilos = newMass; +} + +float Animal::getMass() const +{ + return _massInKilos; +} + +std::string Animal::about() const +{ + return "mass: " + std::to_string(_massInKilos) + "\n"; +} + +Mammal::Mammal() : Animal(), _amountOfTeeth(20) +{ + +} + +void Mammal::setAmountOfTeeth(const float& newAmount) +{ + _amountOfTeeth = newAmount; +} + +float Mammal::getAmountOfTeeth() const +{ + return _amountOfTeeth; +} + +std::string Mammal::about() const +{ + return Animal::about() + "amount of teeth: " + std::to_string(_amountOfTeeth) + "\n"; +} + +Insect::Insect() : Animal(), _amountOfWings(2) +{ + +} + +void Insect::setAmountOfWings(const unsigned int& newAmount) +{ + _amountOfWings = newAmount; +} + +unsigned int Insect::getAmountOfWings() const +{ + return _amountOfWings; +} + +std::string Insect::about() const +{ + return Animal::about() + "amount of wings: " + std::to_string(_amountOfWings) + "\n"; +} + +Cat::Cat() : Mammal(), _eyeColor(color::blue) +{ + +} + +void Cat::setEyeColor(const Cat::color& newColor) +{ + _eyeColor = newColor; +} + +Cat::color Cat::getEyeColor() const +{ + return _eyeColor; +} + +std::string Cat::about() const +{ + return Mammal::about() + "eye color: " + std::to_string((int) _eyeColor) + "\n"; +} + +Dog::Dog() : Mammal(), _barkVolume(50) +{ + +} + +void Dog::setBarkVolume(const float& newVolume) +{ + _barkVolume = newVolume; +} + +float Dog::getBarkVolume() const +{ + return _barkVolume; +} + +std::string Dog::about() const +{ + return Mammal::about() + "bark volume: " + std::to_string(_barkVolume) + "\n"; +} + +Ladybug::Ladybug() : Insect(), _amountOfDots(3) +{ + +} + +void Ladybug::setAmountOfDots(const unsigned int& newAmount) +{ + _amountOfDots = newAmount; +} + +unsigned int Ladybug::getAmountOfDots() const +{ + return _amountOfDots; +} + +std::string Ladybug::about() const +{ + return Insect::about() + "amount of dots: " + std::to_string(_amountOfDots) + "\n"; +} + +Bumblebee::Bumblebee() : Insect(), _amountOfLines(10) +{ + +} + +void Bumblebee::setAmountOfLines(const unsigned int& newAmount) +{ + _amountOfLines = newAmount; +} + +unsigned int Bumblebee::getAmountOfDots() const +{ + return _amountOfLines; +} + +std::string Bumblebee::about() const +{ + return Insect::about() + "amount of lines: " + std::to_string(_amountOfLines) + "\n"; +} + +std::ostream& operator<<(std::ostream& out, const Animal& animal) +{ + return out << animal.about() << std::endl; +} + + +int main() +{ + Bumblebee b; + std::cout << b; + return EXIT_SUCCESS; } \ No newline at end of file diff --git a/animals/animal.h b/animals/animal.h index 83a1944..aec9709 100644 --- a/animals/animal.h +++ b/animals/animal.h @@ -1,18 +1,119 @@ #pragma once +#include #include -class Animal { +class Animal +{ public: - float weight; // kg + void setMass(const float& newMass); + + float getMass() const; + + virtual std::string about() const; + +protected: + Animal(); + + float _massInKilos; }; -class Mammal : public Animal { +class Mammal : public Animal +{ public: - float pregnancyDuration; // days + void setAmountOfTeeth(const float& newAmount); + + float getAmountOfTeeth() const; + + virtual std::string about() const override; + + +protected: + Mammal(); + + unsigned int _amountOfTeeth; }; -class Cat : public Mammal { +class Insect : public Animal +{ public: - float vibrissaLength; // meters + + void setAmountOfWings(const unsigned int& newAmount); + + unsigned int getAmountOfWings() const; + + virtual std::string about() const override; + +protected: + Insect(); + + unsigned int _amountOfWings; }; + +class Cat : public Mammal +{ +public: + enum class color + { + grey = 0, yellow, blue, magenta + }; + + Cat(); + + void setEyeColor(const color& newColor); + + color getEyeColor() const; + + std::string about() const override; + +private: + color _eyeColor; +}; + +class Dog : public Mammal +{ +public: + Dog(); + + void setBarkVolume(const float& newVolume); + + float getBarkVolume() const; + + std::string about() const override; + +private: + + float _barkVolume; +}; + +class Ladybug : public Insect +{ +public: + Ladybug(); + + void setAmountOfDots(const unsigned int& newAmount); + + unsigned int getAmountOfDots() const; + + std::string about() const override; + +private: + unsigned int _amountOfDots; +}; + +class Bumblebee : public Insect +{ +public: + Bumblebee(); + + void setAmountOfLines(const unsigned int& newAmount); + + unsigned int getAmountOfDots() const; + + std::string about() const override; + +private: + unsigned int _amountOfLines; +}; + +std::ostream& operator<<(std::ostream& out, const Animal& animal); \ No newline at end of file diff --git a/electricity/electricity.cpp b/electricity/electricity.cpp index 62da945..9d149d8 100644 --- a/electricity/electricity.cpp +++ b/electricity/electricity.cpp @@ -1,55 +1,219 @@ -#include #include "electricity.h" +#include -using namespace std; +Pole* Pole::getNewInstance() +{ + _poles.emplace_back(new Pole); + return _poles.back(); +} -bool Object::isConnectedTo(const Object& other) const +void Pole::connect(Pole& pole) { - // TODO - return false; + if (_connectedId == pole.getId()) + return; + if (_connectedId) + disconnect(); + _connectedId = pole.getId(); + pole.connect(*this); } -bool Object::connect(const std::string& poleName, Object& other, const std::string& otherPoleName) +void Pole::disconnect() { - // TODO - return false; + unsigned int connectedId = _connectedId; + _connectedId = 0; + if (connectedId) + for (auto& pole: _poles) + if (pole->getId() == connectedId) + pole->disconnect(); +} + +Pole::ID Pole::getId() const +{ + return _id; +} + +Pole::ID Pole::getConnectedId() const +{ + return _connectedId; +} + +bool Pole::send(const std::string& command) +{ + if (!_connectedId) + return false; + for (auto& pole: _poles) + if (pole->getId() == _connectedId) + pole->getCommand(command); + return true; +} + +void Pole::getCommand(const std::string& command) +{ + if (!_connectedId) + return; + if (!command.empty()) + if (_hasCallback) + _callback(command); +} + +Pole::Pole() +{ + _id = ++_total; +} + +Pole::~Pole() +{ + disconnect(); + + for (size_t i = 0; i < _poles.size(); ++i) + if (_poles[i] == this) { + std::swap(_poles[i], _poles.back()); + _poles.pop_back(); + break; + } } -bool Object::disconnect(const std::string& poleName) +void Pole::setCallback(std::function callback) { - // TODO + _callback = std::move(callback); + _hasCallback = true; +} + +const std::string& Object::getName() const +{ + return _name; +} + +bool Object::connect(const Object& object) +{ + if (isConnectedTo(object)) + return true; + Pole* freePole = nullptr; + for (auto& pole: _poles) + if (!pole->getConnectedId()) + freePole = pole; + if (!freePole) + return false; + Pole* pole = object.getFreePole(); + if (!pole) + return false; + freePole->connect(*pole); +} + +void Object::disconnect(const Object& object) +{ + if (!isConnectedTo(object)) + return; + for (auto& a: _poles) + for (auto& b: object.getPoles()) + if (a->getConnectedId() == b->getId()) + a->disconnect(); +} + +bool Object::isConnectedTo(const Object& object) const +{ + for (auto& a: getPoles()) + for (auto& b: object.getPoles()) + if (a == b) + return true; return false; } -Switch::Switch(const std::string& name) - : Object(name) - , a1("A1") - , a2("A2") +std::vector Object::getPoles() const { + return _poles; } -const Pole* Switch::getPole(const string& name) const +Pole* Object::getFreePole() const { - if (name == a1.name) - return &a1; - if (name == a2.name) - return &a2; + for (auto& pole: _poles) + if (!pole->getConnectedId()) + return pole; return nullptr; } -const Pole* Switch::getPole(size_t idx) const +Pole* Object::getPoleConnectedTo(const Object& object) const { - // TODO + for (auto& a: _poles) + for (auto& b: object.getPoles()) + if (a->getConnectedId() == b->getId()) + return a; return nullptr; } -int main() +Object::Object(const std::string& name, unsigned int polesAmount) : _name(name) +{ + for (unsigned int i = 0; i < polesAmount; ++i) + _poles.emplace_back(Pole::getNewInstance()); +} + +Switch::Switch(const std::string& name) : Object(name, 2) { - Switch sw, sw2; - sw.connect("A2", sw2, "A1"); - cout << "is " << (sw.isConnectedTo(sw2) ? "" : "not ") << "connected" << endl; + auto poles = getPoles(); - // TODO: создать цепь из генератора, выключателя и светильника + poles[0]->setCallback([&poles](const std::string& command) { + poles[1]->send(command); + }); - return 0; + poles[1]->setCallback([&poles](const std::string& command) { + poles[0]->send(command); + }); +} + +void Switch::toggle() +{ + for (auto& pole: getPoles()) { + if (isOn) + pole->send("off"); + else + pole->send("on"); + } + isOn = !isOn; } + +Light::Light(const std::string& name) : Object(name, 2) +{ + for (auto& pole: getPoles()) + pole->setCallback([this](const std::string& command) { + if (command == "on") + std::cout << "Lights \"" << getName() << "\" are now on\n"; + else if (command == "off") + std::cout << "Lights \"" << getName() << "\" are now off\n"; + else + std::cout << "Unknown command\n"; + }); +} + +Generator::Generator(const std::string& name) : Object(name, 3) +{} + +int main() +{ + Generator g("Generator"); + + Switch s1("s1"); + Switch s2("s2"); + Switch s3("s3"); + + Light l1("l1"); + Light l2("l2"); + Light l3("l3"); + + g.connect(s1); + g.connect(s2); + g.connect(s3); + + s1.connect(l1); + s2.connect(l2); + s3.connect(l3); + + s2.toggle(); + std::cout << "\n"; + + for (int i = 0; i < 3; ++i) { + s1.toggle(); + s2.toggle(); + s3.toggle(); + std::cout << "\n"; + } +} \ No newline at end of file diff --git a/electricity/electricity.h b/electricity/electricity.h index cb19597..669c5e0 100644 --- a/electricity/electricity.h +++ b/electricity/electricity.h @@ -1,137 +1,87 @@ -#pragma once +#pragma once + +#include #include +#include -class Object; - -/// -/// Полюс устройства. -/// К одному полюсу может быть подключен один любой другой полюс этого же -/// устройства, или же любой полюс любого другого устройства. -/// -/// У каждого полюса есть своё название, которое получает значение по умолчанию -/// при создании устройства, но может быть изменено позднее. -/// -struct Pole { - /// - /// Название полюса. - /// Должно быть уникальным в пределах устройства. - /// - std::string name; - - /// - /// Устройство, подключенное к данному полюсу. - /// Может совпадать с устройством, содержащим данный полюс, при условии, что соединяются - /// два разных полюса. - /// Значение nullptr означает, что к данному полюсу ничего не подключено. - /// - Object* connectedObject; - - /// - /// Полюс устройства, к которому подключен данный полюс. - /// - std::string connectedObjectPole; - - Pole(const std::string& name_) : name(name_), connectedObject(nullptr) {} -}; +class Pole +{ +public: + using ID = unsigned short; -/// -/// Электротехническое устройство. -/// Имеет произвольное неотрицательное количество полюсов (), -/// через которые может соединяться с другими устройствами. -/// -class Object { - std::string name; + static Pole* getNewInstance(); -protected: - Object(const std::string& name_) : name(name_) {} - - /// - /// Возвращает полюс по внутреннему индексу устройства. - /// - /// Индекс полюса, от 0 до значения, возвращаемого . - /// Полюс с указанным индексом, или nullptr, если такой полюс не существует. - Pole* getPole(size_t idx) { /* TODO */ return nullptr; } - - /// - /// Возвращает полюс по внутреннему индексу устройства. - /// - /// Индекс полюса, от 0 до значения, возвращаемого . - /// Полюс с указанным индексом, или nullptr, если такой полюс не существует. - virtual const Pole* getPole(size_t idx) const = 0; + void connect(Pole& pole); -public: - virtual ~Object() {} - - const std::string& getName() const { return name; } - void getName(const std::string &newName) { name = newName; } - - /// - /// Возвращает полюс по имени. - /// - /// Имя полюса. - /// Полюс с указанным именем, или nullptr, если такой полюс не существует. - Pole* getPole(const std::string& name) { return const_cast(const_cast(this)->getPole(name)); } - - /// - /// Возвращает полюс по имени. - /// - /// Имя полюса. - /// Полюс с указанным именем, или nullptr, если такой полюс не существует. - virtual const Pole* getPole(const std::string& name) const = 0; - - /// Количество полюсов в текущем устройстве. - virtual size_t getPoleCount() const = 0; - - /// - /// Проверяет, связаны ли два указанных устройства напрямую через какую-либо пару их полюсов. - /// - /// Устройство, наличие прямой связи с которым проверяется. - /// true если устройства связаны напрямую, false в противном случае. - bool isConnectedTo(const Object& other) const; - - /// - /// Соединяет указанные полюса текущего и указанного устройства. - /// Если к этим полюсам было что-то подключено, то такая связь разрушается. - /// - /// Название подключаемого полюса текущего устройства - /// Устройство, которое связывается с текущим. - /// Название подключаемого полюса другого устройства - /// true если устройства удалось связать, false в противном случае. - /// - /// Может использоваться для связи устройства с самим собой. - /// В этом случае в качестве следует передать то же устройство, - /// для которого вызывается этот метод. - /// - bool connect(const std::string& poleName, Object& other, const std::string& otherPoleName); - - /// - /// Отключает указанный полюс, если к нему что-либо подключено. - /// - /// Название полюса, от которого производится отключение. - /// true если что-либо было отключено, false в противном случае. - /// - /// Вызов этого метода для полюса, если к нему ничего не подключено, не является ошибкой. - /// - bool disconnect(const std::string& poleName); + void disconnect(); + + ID getId() const; + + ID getConnectedId() const; + + bool send(const std::string& command); + + void getCommand(const std::string& command); + + void setCallback(std::function callback); + +private: + Pole(); + + ~Pole(); + + inline static ID _total = 0; + ID _id; + ID _connectedId = 0; + inline static std::vector _poles; + bool _hasCallback = false; + std::function _callback; }; -/// -/// Простой выключатель с двумя полюсами. -/// -class Switch : public Object { +class Object +{ public: - Pole a1, a2; + const std::string& getName() const; - Switch(const std::string& name = ""); + bool connect(const Object& object); - virtual size_t getPoleCount() const { return 2; } + void disconnect(const Object& object); - virtual const Pole* getPole(const std::string& name) const; + bool isConnectedTo(const Object& object) const; + + std::vector getPoles() const; + + Pole* getFreePole() const; + + Pole* getPoleConnectedTo(const Object& object) const; + +private: + std::string _name; + std::vector _poles; protected: - virtual const Pole* getPole(size_t idx) const; + Object(const std::string& name, unsigned int polesAmount); +}; + +class Switch : public Object +{ +public: + Switch(const std::string& name); + + void toggle(); + +private: + bool isOn = false; }; -// TODO: класс светильника с двумя полюсами +class Light : public Object +{ +public: + Light(const std::string& name); +}; -// TODO: класс генератора с тремя полюсами (фаза, нейтраль, земпя). +class Generator : public Object +{ +public: + Generator(const std::string& name); +}; \ No newline at end of file diff --git a/memhacks/memhacks.cpp b/memhacks/memhacks.cpp index 514c868..c59a097 100644 --- a/memhacks/memhacks.cpp +++ b/memhacks/memhacks.cpp @@ -1,57 +1,70 @@ -#include +#include #include "memhacks.h" -using namespace std; +B::B() : b_s("It's b!") +{ + for (auto i = 0; i < sizeof(data) / sizeof(data[0]); i++) + data[i] = i * 2; +} -B::B() : b_s("It's b!") { - for (auto i = 0; i < sizeof(data) / sizeof(data[0]); i++) - data[i] = i * 2; +void printInternals(const B& b) +{ + const A* a = &b, * a2 = a + 1; + std::cout << "Address of b is 0x" << &b << ", address of b.a_s is 0x" << &b.a_s << ", address of b.b_s is 0x" + << &b.b_s << std::endl; + std::cout << "Size of A is " << sizeof(A) << ", size of B is " << sizeof(B) << std::endl; + std::cout << "B string is '" << b.getBString() << "'" << std::endl; + //cout << "B data: "; b.printData(cout); cout << endl; } -/// -/// Выводит на экран адреса и размеры объекта типа и его содержимого. -/// Можно модифицировать для собственных отладочных целей. -/// -/// Изучаемый объект -void printInternals(const B& b) { - const A* a = &b, * a2 = a + 1; - cout << "Address of b is 0x" << &b << ", address of b.a_s is 0x" << &b.a_s << ", address of b.b_s is 0x" << &b.b_s << endl; - cout << "Size of A is " << sizeof(A) << ", size of B is " << sizeof(B) << endl; - cout << "B string is '" << b.getBString() << "'" << endl; - //cout << "B data: "; b.printData(cout); cout << endl; +std::string B::getBStringV() const +{ + return b_s; } -/// -/// Извлекает значение из текущего объекта. -/// Подразумевается, что текущий объект на самом деле представлено классом . -/// -/// Значение B::b_s -std::string A::getBString() const { - // TODO +std::string A::getBString() const +{ + return *((const std::string*) (this + 1)); } -/// -/// Извлекает значения , и -/// из текущего объекта и выводит их в текстовом виде в указанный выходной поток -/// с помощью адресной арифметики. -/// Подразумевается, что текущий объект на самом деле представлено классом . -/// -void A::printData(std::ostream& os) { - // TODO +std::vector B::getBDataV() const +{ + std::vector vec; + for (int i = 0; i < 7; ++i) + vec.push_back(data[i]); + return vec; } -/// -/// Извлекает значения , и -/// из текущего объекта и выводит их в текстовом виде в указанный выходной поток -/// с помощью виртуальных функций, предусмотренных в классе . -/// -void A::printData2(std::ostream& os) { - // TODO +void A::printData(std::ostream& os) +{ + os << "a_s: " << a_s << " b_s: " << getBString() << " data[] = {"; + for (int i = 0; i < 7; ++i) { + os << ((float*) ((std::string*) (this + 1) + 1))[i]; + if (i != 6) + os << ", "; + } + os << "}"; } -int main() +void A::printData2(std::ostream& os) { - B b; - printInternals(b); - return 0; + os << "a_s: " << a_s << " b_s: " << getBStringV() << " data[] = {"; + auto vec = getBDataV(); + for (auto& i: vec) { + os << i; + if (&i != &vec.back()) + os << ", "; + } + os << "}"; } + +int main() +{ + B b; + printInternals(b); + std::cout << "\n\n"; + b.printData(std::cout); + std::cout << "\n\n"; + b.printData2(std::cout); + return 0; +} \ No newline at end of file diff --git a/memhacks/memhacks.h b/memhacks/memhacks.h index 51076b5..281fa2f 100644 --- a/memhacks/memhacks.h +++ b/memhacks/memhacks.h @@ -1,30 +1,45 @@ -#pragma once +#pragma once #include #include +#include -class B; // чтобы можно было объявить printInternals() как friend в классе A +class B; -class A { - std::string a_s; - int foo; +class A +{ +public: + std::string getBString() const; - friend void printInternals(const B&); + void printData(std::ostream& os); -public: - std::string getBString() const; - void printData(std::ostream& os); - void printData2(std::ostream& os); -}; + void printData2(std::ostream& os); + + virtual std::string getBStringV() const = 0; + + virtual std::vector getBDataV() const = 0; -class B : public A { - std::string b_s; - float data[7]; +private: + std::string a_s; + int foo; - friend void printInternals(const B&); + friend void printInternals(const B&); +}; +class B : public A +{ public: - B(); + B(); + + std::string getBStringV() const override; + + std::vector getBDataV() const override; + +private: + std::string b_s; + float data[7]; + + friend void printInternals(const B&); }; -void printInternals(const B& b); +void printInternals(const B&); \ No newline at end of file diff --git a/memhacks/newhacks.cpp b/memhacks/newhacks.cpp index ba359c6..ff7c1d9 100644 --- a/memhacks/newhacks.cpp +++ b/memhacks/newhacks.cpp @@ -1,9 +1,119 @@ #include -#include "memhacks.h" +#include "newhacks.h" -using namespace std; +Foo::Foo() : _id(++_lastId), _data(42.f) +{ + std::cerr << "constructed object #" << _id << " at " << this << std::endl; +} -int main() +Foo::~Foo() +{ + std::cerr << "destructed object #" << _id << " at " << this << std::endl; +} + +void* Foo::operator new(size_t size) +{ + auto p = malloc(size); + std::cerr << "operator new(" << size << ") returns " << p << std::endl; + return p; +} + +void* Foo::operator new[](size_t size) +{ + auto p = malloc(size); + std::cerr << "operator new[](" << size << ") returns " << p << std::endl; + return p; +} + +void Foo::operator delete(void* p) +{ + std::cerr << "operator delete(" << p << ")" << std::endl; + free(p); +} + +void Foo::operator delete[](void* p) +{ + std::cerr << "operator delete[](" << p << ")" << std::endl; + free(p); +} + +Bar::Bar() +{ + std::cerr << "Bar constructor" << std::endl; +} + +Bar::~Bar() +{ + std::cerr << "Bar destructor" << std::endl; +} + +void* Bar::operator new(size_t size) +{ + auto p = malloc(size); + std::cerr << "operator new(" << size << ") returns " << p << " but this is Bar" << std::endl; + return p; +} + +void* Bar::operator new[](size_t size) +{ + auto p = malloc(size); + std::cerr << "operator new[](" << size << ") returns " << p << " but this is Bar" << std::endl; + return p; +} + +void Bar::operator delete(void* p) +{ + std::cerr << "operator delete(" << p << ") but this is Bar" << std::endl; + free(p); +} + +void Bar::operator delete[](void* p) { - return 0; + std::cerr << "operator delete[](" << p << ") but this is Bar" << std::endl; + free(p); } + +Buz::Buz() +{ + std::cerr << "Buz constructor" << std::endl; +} + +Buz::~Buz() +{ + std::cerr << "Buz destructor" << std::endl; +} + +int main() +{ + // Foo + { + Foo foo; + Foo* foo1 = new Foo; + delete foo1; + Foo* foo2 = new Foo[2]; + delete[] foo2; + } + std::cerr << std::endl; + + // Bar + { + Bar bar; + Bar* bar1 = new Bar; + delete bar1; + Bar* bar2 = new Bar[2]; + delete[] bar2; + } + std::cerr << std::endl; + + // Buz + { + Buz buz; +#if 0 + // This will not compile + Buz* buz1 = new Buz; + delete buz1; + Buz* buz2 = new Buz[2]; + delete[] buz2; +#endif + } +} \ No newline at end of file diff --git a/memhacks/newhacks.h b/memhacks/newhacks.h index 079a383..dfaf786 100644 --- a/memhacks/newhacks.h +++ b/memhacks/newhacks.h @@ -1,2 +1,54 @@ #pragma once +class Foo +{ +public: + Foo(); + + ~Foo(); + + static void* operator new(size_t size); + + static void* operator new[](size_t size); + + static void operator delete(void* p); + + static void operator delete[](void* p); + +private: + inline static uint32_t _lastId = 0; + uint32_t _id; + float _data; +}; + +class Bar : public Foo +{ +public: + Bar(); + + ~Bar(); + + static void* operator new(size_t size); + + static void* operator new[](size_t size); + + static void operator delete(void* p); + + static void operator delete[](void* p); +}; + +class Buz : public Foo +{ +public: + Buz(); + + ~Buz(); + + static void* operator new(size_t size) = delete; + + static void* operator new[](size_t size) = delete; + + static void operator delete(void* p) = delete; + + static void operator delete[](void* p) = delete; +}; \ No newline at end of file diff --git a/vectors/vector.cpp b/vectors/vector.cpp index 9777069..244f3a2 100644 --- a/vectors/vector.cpp +++ b/vectors/vector.cpp @@ -1,25 +1,151 @@ -#include #include "vector.h" -using namespace std; +Vector3d::Vector3d() +{ + _data[2] = _data[1] = _data[0] = 0; +} + +Vector3d::Vector3d(const float& value) +{ + _data[2] = _data[1] = _data[0] = value; +} + +Vector3d::Vector3d(const float& a1, const float& a2, const float& a3) +{ + _data[0] = a1; + _data[1] = a2; + _data[2] = a3; +} + +float Vector3d::operator[](const int& index) const +{ + return _data[index]; +} + +float& Vector3d::operator[](const int& index) +{ + return _data[index]; +} + +Vector3d Vector3d::operator+(const Vector3d& other) +{ + return {_data[0] + other[0], _data[1] + other[1], _data[2] + other[2]}; +} + +Vector3d Vector3d::operator-(const Vector3d& other) +{ + return {_data[0] - other[0], _data[1] - other[1], _data[2] - other[2]}; +} + +Vector3d Vector3d::operator*(const float& value) +{ + return {_data[0] * value, _data[1] * value, _data[2] * value}; +} + +Vector3d Vector3d::operator/(const float& value) +{ + return {_data[0] / value, _data[1] / value, _data[2] / value}; +} + +Vector3d Vector3d::operator-() +{ + return {-_data[0], -_data[1], -_data[2]}; +} + +Vector3d Vector3d::operator!() +{ + if (_data[0] == _data[1] && _data[1] == _data[2]) + if (_data[0] == 0) + return {1, 1, 1}; + return {0, 0, 0}; +} -ostream& operator <<(ostream& os, const vector3d& v) { - return os << "{ " << v[0] << ", " << v[1] << ", " << v[2] << " }"; +std::ostream& operator<<(std::ostream& out, const Vector3d& vector) +{ + return out << "{ " << vector[0] << ", " << vector[1] << ", " << vector[2] << " }"; } -int main(int argc, char** argv) { - vector3d v1, v2(12), v3(1, 3, 8); - v1[2] = 54; - //vector3d v4 = v1 + v2, v5 = v1 - v2, v6 = v1 * 0.5f; - //cout << "v4: " << v4 << endl << "v5: " << v5 << endl << "v6: " << v6 << endl; - printf("address of v1: 0x%p, size: %zu bytes\n", &v1, sizeof(v1)); - printf("address of v1.data: 0x%p, size: %zu bytes\n", &v1.data, sizeof(v1.data)); - printf("address of v1.data[-1]: 0x%p, size: %zu bytes\n", &v1.data[-1], sizeof(v1.data[-1])); - printf("address of v1.data[0]: 0x%p, size: %zu bytes\n", &v1.data[0], sizeof(v1.data[0])); - printf("address of v1.data[1]: 0x%p, size: %zu bytes\n", &v1.data[1], sizeof(v1.data[1])); - printf("address of v1.data[2]: 0x%p, size: %zu bytes\n", &v1.data[2], sizeof(v1.data[2])); - printf("address of v1.data[2000]: 0x%p, size: %zu bytes\n", &v1.data[2000], sizeof(v1.data[2000])); +bool test_vector3d() +{ + + struct vec + { + float x, y, z; + }; + + vec a = {1, 2, 3}, b = {4, 5, 6}; + + Vector3d vec1(a.x, a.y, a.z), vec2(b.x, b.y, b.z); - return 0; + bool error = false; + + if (vec1[0] + vec2[0] != a.x + b.x || + vec1[1] + vec2[1] != a.y + b.y || + vec1[2] + vec2[2] != a.z + b.z) { + std::cerr << "Vector3d + Vector3d: " + << "{ " << vec1[0] + vec2[0] << ", " << vec1[1] + vec2[1] << ", " << vec1[2] + vec2[2] << " } != " + << "{ " << a.x + b.x << ", " << a.y + b.y << ", " << a.z + b.z << " }\n"; + error = true; + } + + if (vec1[0] - vec2[0] != (vec1 - vec2)[0] || + vec1[1] - vec2[1] != (vec1 - vec2)[1] || + vec1[2] - vec2[2] != (vec1 - vec2)[2]) { + std::cerr << "Vector3d - Vector3d: " + << "{ " << vec1[0] - vec2[0] << ", " << vec1[1] - vec2[1] << ", " << vec1[2] - vec2[2] << " } != " + << "{ " << a.x - b.x << ", " << a.y - b.y << ", " << a.z - b.z << " }\n"; + error = true; + } + + if (vec1[0] * 4 != a.x * 4 || + vec1[1] * 4 != a.y * 4 || + vec1[2] * 4 != a.z * 4) { + std::cerr << "Vector3d * const: " + << "{ " << vec1[0] * 4 << ", " << vec1[1] * 4 << ", " << vec1[2] * 4 << " } != " + << "{ " << a.x * 4 << ", " << a.y * 4 << ", " << a.z * 4 << " }\n"; + error = true; + } + + if (vec1[0] / 4 != a.x / 4 || + vec1[1] / 4 != a.y / 4 || + vec1[2] / 4 != a.z / 4) { + std::cerr << "Vector3d / const: " + << "{ " << vec1[0] / 4 << ", " << vec1[1] / 4 << ", " << vec1[2] / 4 << " } != " + << "{ " << a.x / 4 << ", " << a.y / 4 << ", " << a.z / 4 << " }\n"; + error = true; + } + + if ((-vec1)[0] != -a.x || + (-vec1)[1] != -a.y || + (-vec1)[2] != -a.z) { + std::cerr << "-Vector3d: " + << "{ " << -vec1[0] << ", " << -vec1[1] << ", " << -vec1[2] << " } != " + << "{ " << -a.x << ", " << -a.y << ", " << -a.z << " }\n"; + error = true; + } + + if (a.x == a.y && a.y == a.z && a.x == 0) { + Vector3d v = !vec1; + if (v[0] != v[1] || v[1] != v[2] || v[0] != 1) { + std::cerr << "!Vector3d:" + << "{ " << v[0] << ", " << v[1] << ", " << v[2] << " } != " + << "{ " << 1 << ", " << 1 << ", " << 1 << " }\n"; + error = true; + } + else if (v[0] != v[1] || v[1] != v[2] || v[0] != 1) { + std::cerr << "!Vector3d:" + << "{ " << v[0] << ", " << v[1] << ", " << v[2] << " } != " + << "{ " << 0 << ", " << 0 << ", " << 0 << " }\n"; + error = true; + } + } + + return error; } + +int main() +{ + std::cout << test_vector3d << std::endl; + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/vectors/vector.h b/vectors/vector.h index 07587fb..6970a7d 100644 --- a/vectors/vector.h +++ b/vectors/vector.h @@ -1,19 +1,34 @@ #pragma once -#include - -class vector3d { - float data[3]; +#include +class Vector3d +{ public: - vector3d() { data[2] = data[1] = data[0] = 0; } - vector3d(float value) { data[2] = data[1] = data[0] = value; } - vector3d(float a1, float a2, float a3) { data[0] = a1; data[1] = a2; data[2] = a3; } + Vector3d(); + + Vector3d(const float& value); + + Vector3d(const float& a1, const float& a2, const float& a3); + + float operator[](const int& index) const; + + float& operator[](const int& index); + + Vector3d operator+(const Vector3d& other); + + Vector3d operator-(const Vector3d& other); + + Vector3d operator*(const float& value); + + Vector3d operator/(const float& value); + + Vector3d operator-(); - float& operator[](int idx) { return data[idx]; } - float operator[](int idx) const { return data[idx]; } + Vector3d operator!(); - friend int main(int argc, char** argv); +private: + float _data[3]; }; -std::ostream& operator <<(std::ostream& os, const vector3d& v); +std::ostream& operator<<(std::ostream& os, const Vector3d& vector); \ No newline at end of file