Ich schreibe gerade eine Protokollierklasse (nur für die Praxis) und stieß auf ein Problem. Ich habe zwei Klassen: Die Klasse Buffer fungiert als temporärer Puffer und löscht sich selbst in ihrem Destruktor. Und die Klasse Proxy, die eine Buffer-Instanz zurückgibt, so dass ich nicht ständig Buffer() schreiben muss.Verwendung des Kopierkonstruktors erzwingen/Verwendung des Kopierkonstruktors vermeiden
Anyways, hier ist der Code:
#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;
}
Hier ist der Ausgang:
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
Der Code macht genau das, was ich will, aber es hängt von RVO. Ich las mehrere Male, dass Sie nicht auf RVO verlassen sollte, so wollte ich fragen, wie ich kann:
- RVO völlig vermeiden, so dass die Copykonstruktor jedes Mal
- Vermeiden Sie den Copykonstruktor
Ich habe bereits versucht, den Kopierkonstruktor zu vermeiden, indem ich eine Referenz zurücksende oder die segfaults verschiebe. Ich denke, das ist, weil das temporäre Proxy :: operator < < bei der Rückkehr gelöscht wird.
Ich würde auch an ganz anderen Ansätzen interessiert sein, die ungefähr dasselbe tun.
3. Schreiben Sie Code, der nicht davon abhängt, ob RVO passiert. – juanchopanza
Ich denke, das ist die offensichtliche Wahl. Aber ich wollte einen Kopierkonstruktor vermeiden, der höchstwahrscheinlich nie aufgerufen wird. – Schore
Ihre Klasse sollte sowieso nicht kopierbar oder zuweisbar sein (sie hat ein Datenelement 'stringstream'). Ich weiß wirklich nicht, welches Problem Sie hier lösen wollen. – juanchopanza