Задать вопрос
s_n_a_i_l
@s_n_a_i_l
Люблю тратить время в видеоиграх и книгах

Почему bool оператор возвращает false, хотя на деле условия для true соблюдены?

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <stdexcept>



namespace our
{
	template <typename O>
	class Overcoat;

	template <typename O> 
	std::istream& operator>>(std::istream& istream, Overcoat<O>& overcoat);

	template <typename O>
	std::ostream& operator<<(std::ostream& ostream, const Overcoat<O>& overcoat);

	const size_t BUFFER_SIZE = 1024;
}

template <typename O>
class our::Overcoat
{
public:

	Overcoat();
	explicit Overcoat(const O *top, const O *bottom, const O *shoes,
		const size_t priceTop, const size_t priceBottom, const size_t priceShoes);
	Overcoat(const Overcoat& other) noexcept : Overcoat(other.top_, other.bottom_,
		other.shoes_, other.priceTop_, other.priceBottom_, other.priceShoes_) {}
	Overcoat(Overcoat&& other);
	~Overcoat();

	template <typename O>
	friend std::istream& our::operator>>(std::istream& istream, Overcoat<O>& overcoat);

	template <typename O>
	friend std::ostream& our::operator<<(std::ostream& ostream, const Overcoat<O>& overcoat);

	Overcoat& operator=(const Overcoat& other);

	bool operator==(const Overcoat& other) const;
	bool operator>(const Overcoat& other) const;
	bool operator<(const Overcoat& other) const;

	void printHeader() const;


private:
	O* top_, *bottom_, *shoes_;
	size_t priceTop_, priceBottom_, priceShoes_;
};

template <typename O>
void our::Overcoat<O>::printHeader() const
{
	std::cout << "\nEnter as an example: "
		<< "\nTop name : jacket"
		<< "\nTop price : 50"
		<< "\nBottom name : jeans"
		<< "\nBottom price : 20"
		<< "\nShoes name : shoes"
		<< "\nShoes price : 12" << '\n';
}


template <typename O>
bool our::Overcoat<O>::operator<(const Overcoat& other) const 
{
	if (top_ == other.top_)
		return priceTop_ < other.priceTop_;
}

template <typename O>
bool our::Overcoat<O>::operator>(const Overcoat& other) const 
{
	if (top_ == other.top_)
		return priceTop_ > other.priceTop_;
}

template <typename O>
bool our::Overcoat<O>::operator==(const Overcoat& other) const 
{
	return top_ == other.top_ && bottom_ == other.bottom_ && shoes_ == other.shoes_;
}

template <typename O>
our::Overcoat<O>::Overcoat()
{
	top_ = nullptr;
	bottom_ = nullptr;
	shoes_ = nullptr;
	priceTop_ = 0;
	priceBottom_ = 0;
	priceShoes_ = 0;
}

template <typename O>
our::Overcoat<O>::Overcoat(const O* top, const O* bottom, const O* shoes,
	const size_t priceTop, const size_t priceBottom, const size_t priceShoes)
{
	if(priceTop < 0 || priceBottom < 0 || priceShoes < 0)
	{
		throw std::invalid_argument("The price cannot be negative!");
	}

	if (top == nullptr || bottom == nullptr || shoes == nullptr) 
	{
		throw std::invalid_argument("Pointers must not be nullptr!");
	}
	
	top_ = new O[std::strlen(top) + 1];
	std::strcpy(top_, top);
	priceTop_ = priceTop;

	bottom_ = new O[std::strlen(bottom) + 1];
	std::strcpy(bottom_, bottom);
	priceBottom_ = priceBottom;

	shoes_ = new O[std::strlen(shoes) + 1];
	std::strcpy(shoes_, shoes);
	priceShoes_ = priceShoes;
	
}

template <typename O>
our::Overcoat<O>::Overcoat( Overcoat&& other)
{
	if (other.top == nullptr || other.bottom == nullptr || other.shoes == nullptr)
	{
		throw std::invalid_argument("Pointers must not be nullptr");
	}

	top_ = other.top_;
	bottom_ = other.bottom_;
	shoes_ = other.shoes_;

	other.top_ = nullptr;
	other.bottom_ = nullptr;
	other.shoes_ = nullptr;
}

template <typename O>
our::Overcoat<O>::~Overcoat() 
{
	delete[] top_;
	delete[] bottom_;
	delete[] shoes_;
}

template <typename O>
our::Overcoat<O>& our::Overcoat<O>::operator=(const Overcoat& other)
{
	if (this == &other)
	{
		std::clog << "Self assignement!!!";
		return *this;
	}

	delete[] top_;
	delete[] bottom_;
	delete[] shoes_;
   
	top_ = new O[std::strlen(other.top_) + 1];
	std::strcpy(top_, other.top_);
	priceTop_ = other.priceTop_;

	bottom_ = new O[std::strlen(other.bottom_) + 1];
	std::strcpy(bottom_, other.bottom_);
	priceBottom_ = other.priceBottom_;

	shoes_ = new O[std::strlen(other.shoes_) + 1];
	std::strcpy(shoes_, other.shoes_);
	priceShoes_ = other.priceShoes_;

	return *this;
}

template <typename O>
std::istream& our::operator>>(std::istream& istream, Overcoat<O>& overcoat)
{
	overcoat.printHeader();

	O* const buffer = new O[BUFFER_SIZE];

	std::cin.getline(buffer, BUFFER_SIZE);
	istream >> overcoat.priceTop_;
	std::cin.ignore();
	overcoat.top_ = new O[std::strlen(buffer) + 1];
	std::strcpy(overcoat.top_, buffer);
	
	std::cin.getline(buffer, BUFFER_SIZE);
	istream >> overcoat.priceBottom_;
	std::cin.ignore();
	overcoat.bottom_ = new O[std::strlen(buffer) + 1];
	std::strcpy(overcoat.bottom_, buffer);
	

	std::cin.getline(buffer, BUFFER_SIZE);
	istream >> overcoat.priceShoes_;
	std::cin.ignore();
	overcoat.shoes_ = new O[std::strlen(buffer) + 1];
	std::strcpy(overcoat.shoes_, buffer);
	
    delete[] buffer;
	return istream;
}

template <typename O>
std::ostream& our::operator<<(std::ostream& ostream, const Overcoat<O>& overcoat)
{
	if (overcoat.top_ == nullptr || overcoat.bottom_ == nullptr || overcoat.shoes_ == nullptr)
		throw std::invalid_argument("Pointers are empty!");
	
	ostream << "\nTop: " << overcoat.top_ << "\tits prise: " << overcoat.priceTop_
		<< "\nBottom: " << overcoat.bottom_ << "\tits prise: " << overcoat.priceBottom_
		<< "\nShoes: " << overcoat.shoes_ << "\tits prise: " << overcoat.priceShoes_<< std::endl;

	return ostream;
}

#define _CRT_SECURE_NO_WARNINGS
#include "Overcoat.h"

int main()
{
	try
	{
		our::Overcoat<char> a("top","bottom","shues",20,12,3), b("topik", "bottomom", "shueses", 25, 16, 9), e;
		//std::cin >> a >> b;
		std::cout << a << b;

		std::cout << std::boolalpha << (a > b) << std::endl;//только для верха
		std::cout << std::boolalpha << (a == b) << std::endl;//сравнивает верх низ и обувь

		e = a;
		std::cout << e << a;
		std::cout << std::boolalpha << (e == a) << std::endl;
	}  
	catch(const char* const error)
	{
		std::cerr << error;
		return 1;
	}
}


Подскажите пожалуйста, почему оператор > или оператор ==, работают некорректно. Не могу понять что упустила, может где-то логическая ошибка.
  • Вопрос задан
  • 81 просмотр
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 1
@Mercury13
Программист на «си с крестами» и не только
Стандартная ошибка наплюсника, аж две штуки.

МАКРО-УРОВЕНЬ: вы пишете свою строку, но вместо того, чтобы сделать её отдельным объектом, инкапсулируете внутри Overcoat.

Рисунок кода Си++ в точности обратный — всё, что умеет удерживать-отдавать ресурсы, переносится в отдельный объект небольшого размера. К тому же использование таких вот небольших объектов позволяет идиому «by-value+move»: если параметр — временная our::String, она просто переносится, а если нет — ну йок так йок.

НЕПОСРЕДСТВЕННАЯ ПРИЧИНА: сравниваете указатели на буфера, а не содержимое строк.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы