В настоящее время я пишу класс ведения журнала (только для практики) и столкнулся с проблемой. У меня есть два класса: класс Buffer действует как временный буфер и сбрасывает себя в деструктор. И класс Proxy, который возвращает экземпляр Buffer, поэтому мне не нужно писать Buffer() все время.Принудительное использование конструктора копирования/Избегайте использования конструктора копирования
В любом случае, вот код:
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
class Buffer
{
private:
std::stringstream buf;
public:
Buffer(){};
template <typename T>
Buffer(const T& v)
{
buf << v;
std::cout << "Constructor called\n";
};
~Buffer()
{
std::cout << "HEADER: " << buf.str() << "\n";
}
Buffer(const Buffer& b)
{
std::cout << "Copy-constructor called\n";
// How to get rid of this?
};
Buffer(Buffer&&) = default;
Buffer& operator=(const Buffer&) & = delete;
Buffer& operator=(Buffer&&) & = delete;
template <typename T>
Buffer& operator<<(const T& v)
{
buf << v;
return *this;
}
};
class Proxy
{
public:
Proxy(){};
~Proxy(){};
Proxy(const Proxy&) = delete;
Proxy(Proxy&&) = delete;
Proxy& operator=(const Proxy&) & = delete;
Proxy& operator=(Proxy&&) & = delete;
template <typename T>
Buffer operator<<(const T& v) const
{
if(v < 0)
return Buffer();
else
return Buffer(v);
}
};
int main() {
Buffer(Buffer() << "Test") << "what";
Buffer() << "This " << "works " << "fine";
const Proxy pr;
pr << "This " << "doesn't " << "use the copy-constructor";
pr << "This is a " << std::setw(10) << " test";
return 0;
}
Здесь выход:
Copy-constructor called
HEADER: what
HEADER: Test
HEADER: This works fine
Constructor called
HEADER: This doesn't use the copy-constructor
Constructor called
HEADER: This is a test
код делает именно то, что я хочу, но это зависит от РВО. Я прочитал несколько раз, что вы не должны полагаться на РВО, так что я хотел бы спросить, как я могу:
- Избегайте РВО полностью, так что конструктор копирования вызывается каждый раз, когда
- Избегайте конструктор копирования
Я уже пытался избежать конструктора копирования, возвращая ссылку или перемещаясь, но это segfaults. Думаю, это потому, что временный оператор Proxy :: < < удален во время возврата.
Меня также интересуют совершенно разные подходы, которые делают примерно то же самое.
3. Напишите код, который не зависит от того, происходит ли RVO. – juanchopanza
Я предполагаю, что это очевидный выбор. Но я хотел избежать конструктора копирования, который, скорее всего, никогда не будет вызван. – Schore
Ваш класс не должен копироваться или присваиваться в любом случае (у него есть член данных 'stringstream'.) Я действительно не знаю, какую проблему вы пытаетесь решить здесь. – juanchopanza