Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
June 22, 2012 const behaviour | ||||
---|---|---|---|---|
| ||||
Based to the current const discussions (once again) I wanted to appease my curiosity and want to ask why the following code works as described in the comments: [code] import std.stdio; class Bar { } class Foo { private: string _text; Bar _b; public: this(string text, Bar b) { this._text = text; this._b = b; } // const_behaviour.d(18): Error: cannot implicitly convert expression (this._b) of type const(Bar) to const_behaviour.Bar Bar GetB() const pure nothrow { /// <- must be const(Bar) instead of Bar return this._b; } string GetText() const pure nothrow { /// <- no const(string) is neccessary. Why? return this._text; } } void main() { Bar b = new Bar(); Foo f = new Foo("foobar", b); } [/code] |
June 22, 2012 Re: const behaviour | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On 06/22/2012 11:21 AM, Namespace wrote:
> Based to the current const discussions (once again) I wanted to appease
> my curiosity and want to ask why the following code works as described
> in the comments:
>
> [code]
>
> import std.stdio;
>
> class Bar { }
>
> class Foo {
> private:
> string _text;
>
> Bar _b;
>
> public:
> this(string text, Bar b) {
> this._text = text;
> this._b = b;
> }
>
> // const_behaviour.d(18): Error: cannot implicitly convert
> expression (this._b) of type const(Bar) to const_behaviour.Bar
> Bar GetB() const pure nothrow { /// <- must be const(Bar) instead
> of Bar
> return this._b;
> }
>
> string GetText() const pure nothrow { /// <- no const(string) is
> neccessary. Why?
> return this._text;
> }
> }
>
> void main() {
> Bar b = new Bar();
>
> Foo f = new Foo("foobar", b);
> }
>
> [/code]
string is immutable(char)[] and const(immutable(char)[]) implicitly
converts to immutable(char)[]. Or put differently, a string doesn't
have to be const-qualified because it cannot be changed anyway.
|
June 22, 2012 Re: const behaviour | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | As far as i know "int" is not immutable or const by default. So, why work this code: [code] import std.stdio; class Bar { } class Foo { private: int _id; Bar _b; public: this(int id, Bar b) { this._id = id; this._b = b; } // const_behaviour.d(18): Error: cannot implicitly convert expression (this._b) of type const(Bar) to const_behaviour.Bar const(Bar) GetB() const pure nothrow { /// <- must be const(Bar) instead of Bar return this._b; } int GetId() const pure nothrow { /// <- no const(int) is neccessary. Why?! return this._id; } } void main() { Bar b = new Bar(); Foo f = new Foo(42, b); } [/code] |
June 22, 2012 Re: const behaviour | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On 06/22/2012 12:25 PM, Namespace wrote:
> As far as i know "int" is not immutable or const by default.
> So, why work this code:
>
> [code]
> import std.stdio;
>
> class Bar {
>
> }
>
> class Foo {
> private:
> int _id;
>
> Bar _b;
>
> public:
> this(int id, Bar b) {
> this._id = id;
>
> this._b = b;
> }
>
> // const_behaviour.d(18): Error: cannot implicitly convert
> expression (this._b) of type const(Bar) to const_behaviour.Bar
> const(Bar) GetB() const pure nothrow { /// <- must be const(Bar)
> instead of Bar
> return this._b;
> }
>
> int GetId() const pure nothrow { /// <- no const(int) is
> neccessary. Why?!
> return this._id;
> }
> }
>
> void main() {
> Bar b = new Bar();
>
> Foo f = new Foo(42, b);
> }
> [/code]
The same reason, because const(int) implicitly converts to int. If the
data is copied, the qualifiers can be changed in any way that is
desired. As string, int has no mutable indirections.
|
June 22, 2012 Re: const behaviour | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On 06/22/2012 02:21 AM, Namespace wrote:
> Based to the current const discussions (once again) I wanted to appease
> my curiosity and want to ask why the following code works as described
> in the comments:
>
> [code]
>
> import std.stdio;
>
> class Bar { }
>
> class Foo {
> private:
> string _text;
_text is a reference to immutable(char).
>
> Bar _b;
_b is a reference to mutable Bar.
>
> public:
> this(string text, Bar b) {
> this._text = text;
> this._b = b;
> }
>
> // const_behaviour.d(18): Error: cannot implicitly convert expression
> (this._b) of type const(Bar) to const_behaviour.Bar
> Bar GetB() const pure nothrow {
That function promises that the object will not be modified through it.
> /// <- must be const(Bar) instead of Bar
That is not entirely correct. The return type need not be const(Bar). The problem is with what you are returning.
> return this._b;
That is the problem. To enforce its no-mutation guarantee, the function cannot return a non-const reference to the Bar object that _b is a reference of. The return type Bar compiles with this code:
Bar GetB() const pure nothrow {
return new Bar();
}
> }
>
> string GetText() const pure nothrow { /// <- no const(string) is
> neccessary. Why?
Because _text is a non-mutating reference.
> return this._text;
> }
> }
>
> void main() {
> Bar b = new Bar();
>
> Foo f = new Foo("foobar", b);
> }
>
> [/code]
Note that the caller can modify the string that GetText() returns by e.g. appending to it:
string t = f.GetText();
t is a copy of _text. They currently share the same characters: "foobar".
t ~= "zar";
The act of appending does not change _text in any way. It still refers to "foobar".
Ali
--
D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html
|
Copyright © 1999-2021 by the D Language Foundation