<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[std::vector: Konstruktor-Verhalten ändern]]></title><description><![CDATA[<p>Hallo!<br />
Es ist nur eine kurze Frage. Undzwar habe ich einen <code>vector</code> , der Wrapper um OS-Handles beinhalten soll. Diese Handles werden beim Aufruf des Default-Konstruktors vom Wrapper generiert, folglich hätte ich bei diesem Beispiel verschiedene Handles in den Wrappern:</p>
<pre><code class="language-cpp">handle_wrapper handles[3]; // Ruft 5 mal handle_wrapper::handle_wrapper() auf
for(handle_wrapper handle : handles) cout &lt;&lt; handle &lt;&lt; endl;

/*
Output:
56
60
64
*/
</code></pre>
<p>Allerdings ist <code>vector</code> da ja etwas anders: es kopiert immer das erste Element für die übrigen:</p>
<pre><code class="language-cpp">vector&lt;handle_wrapper&gt; handles(3/*, handle_wrapper()*/);
for(handle_wrapper handle : handles) cout &lt;&lt; handle &lt;&lt; endl;

/*
Output:
56
56
56
*/
</code></pre>
<p>Kann man da <code>vector</code> irgendwie anpassen? Die Handles dann noch mal extra auf dem Heap zu alloziieren und Zeiger im <code>vector</code> zu speichern fände ich doof.<br />
Gibt's da eine Möglichkeit?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/267424/std-vector-konstruktor-verhalten-ändern</link><generator>RSS for Node</generator><lastBuildDate>Wed, 02 Sep 2026 14:26:44 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/267424.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 24 May 2010 13:14:20 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to std::vector: Konstruktor-Verhalten ändern on Mon, 24 May 2010 14:26:03 GMT]]></title><description><![CDATA[<p>Hallo!<br />
Es ist nur eine kurze Frage. Undzwar habe ich einen <code>vector</code> , der Wrapper um OS-Handles beinhalten soll. Diese Handles werden beim Aufruf des Default-Konstruktors vom Wrapper generiert, folglich hätte ich bei diesem Beispiel verschiedene Handles in den Wrappern:</p>
<pre><code class="language-cpp">handle_wrapper handles[3]; // Ruft 5 mal handle_wrapper::handle_wrapper() auf
for(handle_wrapper handle : handles) cout &lt;&lt; handle &lt;&lt; endl;

/*
Output:
56
60
64
*/
</code></pre>
<p>Allerdings ist <code>vector</code> da ja etwas anders: es kopiert immer das erste Element für die übrigen:</p>
<pre><code class="language-cpp">vector&lt;handle_wrapper&gt; handles(3/*, handle_wrapper()*/);
for(handle_wrapper handle : handles) cout &lt;&lt; handle &lt;&lt; endl;

/*
Output:
56
56
56
*/
</code></pre>
<p>Kann man da <code>vector</code> irgendwie anpassen? Die Handles dann noch mal extra auf dem Heap zu alloziieren und Zeiger im <code>vector</code> zu speichern fände ich doof.<br />
Gibt's da eine Möglichkeit?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1901870</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1901870</guid><dc:creator><![CDATA[Ad aCTa]]></dc:creator><pubDate>Mon, 24 May 2010 14:26:03 GMT</pubDate></item><item><title><![CDATA[Reply to std::vector: Konstruktor-Verhalten ändern on Mon, 24 May 2010 13:23:52 GMT]]></title><description><![CDATA[<p>Es ist nicht gut, wenn deine <code>handle_wrapper</code> -Klasse keine übliche Value-Semantik unterstützt. Der <code>std::vector</code> darf davon ausgehen, dass die beiden Zeilen semantisch äquivalent sind:</p>
<pre><code class="language-cpp">T a = T();
T a;
</code></pre>
<p>Ich denke, hier liegt das Problem. Normalerweise gilt auch</p>
<pre><code class="language-cpp">T a;
T b;
assert(a == b);
</code></pre>
<p>Also solltest du nicht den Defaultkonstruktor für spezielle Werte verwenden, sondern eher eine Factory-Funktion, mit der du die Objekte initialisierst.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1901877</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1901877</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 24 May 2010 13:23:52 GMT</pubDate></item><item><title><![CDATA[Reply to std::vector: Konstruktor-Verhalten ändern on Mon, 24 May 2010 14:25:07 GMT]]></title><description><![CDATA[<p>Hm... würde man das als &quot;schöner&quot; bezeichnen?</p>
<pre><code class="language-cpp">typedef shared_ptr&lt;handle_wrapper&gt; hptr_t;

class handle_wrapper {
public:
	/* some */
	friend hptr_t create_socket();

private:
	handle_wrapper() {
		/* some */
	}
	// ...
};

hptr_t create_socket() {
	return hptr_t(new socket_handle);
}

// ...

vector&lt;sockptr_t&gt; handles(5);
for(sockptr_t&amp; handle : handles) {
	sh = create_socket();
	cout &lt;&lt; sh-&gt;get() &lt;&lt; endl;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1901915</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1901915</guid><dc:creator><![CDATA[Ad aCTa]]></dc:creator><pubDate>Mon, 24 May 2010 14:25:07 GMT</pubDate></item><item><title><![CDATA[Reply to std::vector: Konstruktor-Verhalten ändern on Mon, 24 May 2010 14:40:56 GMT]]></title><description><![CDATA[<p>Warum jetzt plötzlich <code>shared_ptr</code> ? Das brauchst du doch nicht.</p>
<p>Ich hätte eher an sowas gedacht:</p>
<pre><code class="language-cpp">handle_wrapper create_socket();

int main()
{
   std::vector&lt;handle_wrapper&gt; vector;
   std::generate_n(std::back_inserter(vector), 5, &amp;create_socket);
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1901928</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1901928</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 24 May 2010 14:40:56 GMT</pubDate></item><item><title><![CDATA[Reply to std::vector: Konstruktor-Verhalten ändern on Mon, 24 May 2010 15:07:34 GMT]]></title><description><![CDATA[<p>Das macht leider eine Copy-Operation?! Jedenfalls sind im <code>vector</code> dann die selben Handle-Werte.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1901937</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1901937</guid><dc:creator><![CDATA[Ad aCTa]]></dc:creator><pubDate>Mon, 24 May 2010 15:07:34 GMT</pubDate></item><item><title><![CDATA[Reply to std::vector: Konstruktor-Verhalten ändern on Mon, 24 May 2010 15:14:56 GMT]]></title><description><![CDATA[<p>Ad aCTa schrieb:</p>
<blockquote>
<p>Das macht leider eine Copy-Operation?! Jedenfalls sind im <code>vector</code> dann die selben Handle-Werte.</p>
</blockquote>
<p>Sofern du <code>create_socket()</code> so implementierst, dass es nicht jedes Mal dasselbe Objekt zurückgibt, sind die neuen Elemente im <code>std::vector</code> auch unterschiedlich.</p>
<p>Die STL-Algorithmen <code>std::generate()</code> und <code>std::generate_n()</code> rufen die Generatorfunktion für jedes Element auf – etwa im Gegensatz zu <code>std::fill()</code> und <code>std::fill_n()</code> .</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1901939</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1901939</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 24 May 2010 15:14:56 GMT</pubDate></item><item><title><![CDATA[Reply to std::vector: Konstruktor-Verhalten ändern on Mon, 24 May 2010 15:18:11 GMT]]></title><description><![CDATA[<blockquote>
<p>&gt; Sofern du create_socket() so implementierst, dass es nicht jedes Mal dasselbe Objekt zurückgibt, sind die neuen Elemente im std::vector auch unterschiedlich.</p>
</blockquote>
<p>Das will ich auch meinen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /> Die Implementierung der Funktion ist trivial:</p>
<pre><code class="language-cpp">inline socket_handle create_socket() {
	return socket_handle();
}
</code></pre>
<p>Dabei kann es ja unmöglich immer das selbe Objekt sein?!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1901942</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1901942</guid><dc:creator><![CDATA[Ad aCTa]]></dc:creator><pubDate>Mon, 24 May 2010 15:18:11 GMT</pubDate></item><item><title><![CDATA[Reply to std::vector: Konstruktor-Verhalten ändern on Mon, 24 May 2010 15:32:03 GMT]]></title><description><![CDATA[<p>Ad aCTa schrieb:</p>
<blockquote>
<p>Dabei kann es ja unmöglich immer das selbe Objekt sein?!</p>
</blockquote>
<p>Wenn du meinen Rat befolgt hast und der Defaultkonstruktor immer die gleiche Initialisierung durchführt, doch. Ansonsten passe deine Wertsemantik an, dass</p>
<pre><code class="language-cpp">socket_handle a;
socket_handle b;
assert(a == b);
</code></pre>
<p>gilt (falls <code>operator==</code> nicht existiert, denk dir eine sinnvolle Implementierung für dieses Gedankenexperiment aus).</p>
<p>Objekt-spezifische Initialisierungen sollten wie schon gesagt nicht im Defaultkonstruktor geschehen. Entsprechend müsste <code>create_socket()</code> auch mehr tun als nur Default- und Kopierkonstruktor aufzurufen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1901947</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1901947</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 24 May 2010 15:32:03 GMT</pubDate></item><item><title><![CDATA[Reply to std::vector: Konstruktor-Verhalten ändern on Mon, 24 May 2010 15:38:28 GMT]]></title><description><![CDATA[<p>Das ändert nichts. Selbst wenn ich die Semantik herstelle und</p>
<pre><code class="language-cpp">inline socket_handle create_socket() {
	socket_handle sh;
	sh.init_();
	return sh;
}
</code></pre>
<p>schreibe, bleiben die Handles gleich?!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1901949</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1901949</guid><dc:creator><![CDATA[Ad aCTa]]></dc:creator><pubDate>Mon, 24 May 2010 15:38:28 GMT</pubDate></item><item><title><![CDATA[Reply to std::vector: Konstruktor-Verhalten ändern on Mon, 24 May 2010 15:43:29 GMT]]></title><description><![CDATA[<p>Kannst du diesen Code kompilieren und sagen, wie bei dir die Ausgabe aussieht?</p>
<pre><code class="language-cpp">#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;iterator&gt;
#include &lt;iostream&gt;

int create_int()
{
	static int i;
	return ++i;
}

void output(int i)
{
	std::cout &lt;&lt; i &lt;&lt; &quot; &quot;;
}

int main()
{
   std::vector&lt;int&gt; vector;
   std::generate_n(std::back_inserter(vector), 5, &amp;create_int);
   std::for_each(vector.begin(), vector.end(), &amp;output);
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1901952</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1901952</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 24 May 2010 15:43:29 GMT</pubDate></item><item><title><![CDATA[Reply to std::vector: Konstruktor-Verhalten ändern on Mon, 24 May 2010 15:50:58 GMT]]></title><description><![CDATA[<p>Logischerweise 1 2 3 4 5.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1901954</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1901954</guid><dc:creator><![CDATA[Ad aCTa]]></dc:creator><pubDate>Mon, 24 May 2010 15:50:58 GMT</pubDate></item><item><title><![CDATA[Reply to std::vector: Konstruktor-Verhalten ändern on Mon, 24 May 2010 15:54:32 GMT]]></title><description><![CDATA[<p>Gut, also ist deine Implementierung von <code>generate_n()</code> in Ordnung.</p>
<p>Kannst du etwas mehr Code posten? Wie sehen Kopier- und Standardkonstruktor von <code>socket_handle</code> aus? Kannst du die Funktion <code>create_socket()</code> und die Stelle ihrer Verwendung (beim Füllen des Containers) zeigen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1901955</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1901955</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 24 May 2010 15:54:32 GMT</pubDate></item><item><title><![CDATA[Reply to std::vector: Konstruktor-Verhalten ändern on Mon, 24 May 2010 16:29:59 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">vector&lt;socket_handle&gt; sockets;
generate_n(std::back_inserter(sockets), 3, create_socket);
for_each(sockets.begin(), sockets.end(), [](const socket_handle&amp; sh) {
	cout &lt;&lt; sh.get() &lt;&lt; endl;
});

// Kopierkonstruktor und Zuweisungsoperator sind compilergeneriert

inline socket_handle create_socket() {
	socket_handle sh;
	sh.init_();
	return sh;
}

struct socket_handle {
	socket_handle() throw(std::runtime_error)
		: used_(false), handle_(0)
	{ }

	bool used() const { return used_; }
	~socket_handle() { /* Handle freigeben */ }
	const SOCKET&amp; get() const throw() { return handle_; }

	friend socket_handle create_socket();

private:
	void init_() {
		// Handle anfordern
	}

	bool used_;
	SOCKET handle_;
};
</code></pre>
<p>Nicht mehr und nicht weniger.</p>
<p>// EDIT:</p>
<p>Au weia, jetzt fällt mir was ein. Da der Destruktor ja beim Beenden von <code>create_socket</code> aufgerufen wird, wird die Ressource freigegeben, sodass es beim nächsten Aufruf wieder die selbe Ressource ist, die ich dann bekomme. Scheinbar muss ich doch den Heap benutzen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1901967</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1901967</guid><dc:creator><![CDATA[Ad aCTa]]></dc:creator><pubDate>Mon, 24 May 2010 16:29:59 GMT</pubDate></item><item><title><![CDATA[Reply to std::vector: Konstruktor-Verhalten ändern on Mon, 24 May 2010 16:50:56 GMT]]></title><description><![CDATA[<p>So, ich glaube, in diesem Fall ist das gute alte Array immernoch die einfachste Lösung. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1901973</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1901973</guid><dc:creator><![CDATA[Ad aCTa]]></dc:creator><pubDate>Mon, 24 May 2010 16:50:56 GMT</pubDate></item><item><title><![CDATA[Reply to std::vector: Konstruktor-Verhalten ändern on Mon, 24 May 2010 17:07:26 GMT]]></title><description><![CDATA[<p>Ad aCTa schrieb:</p>
<blockquote>
<p>Au weia, jetzt fällt mir was ein. Da der Destruktor ja beim Beenden von <code>create_socket</code> aufgerufen wird, wird die Ressource freigegeben, sodass es beim nächsten Aufruf wieder die selbe Ressource ist, die ich dann bekomme. Scheinbar muss ich doch den Heap benutzen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
</blockquote>
<p>Ja, dann scheint das sinnvoll zu sein. Wäre ja auch blöd, wenn bei einer Vector-Reallokation plötzlich alle Ressourcen freigegeben würden. Daher immer schön schauen, dass man so oft wie möglich eine sinnvolle Wertsemantik hat, besonders bei Containern. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Ad aCTa schrieb:</p>
<blockquote>
<p>So, ich glaube, in diesem Fall ist das gute alte Array immernoch die einfachste Lösung. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
</blockquote>
<p>Wenigstens <code>std::tr1::array</code> läge also schon drin. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1901979</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1901979</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 24 May 2010 17:07:26 GMT</pubDate></item></channel></rss>