🌻天国にいけるC++言語入門🌻 進化し続けるオブジェクト指向プログラミング ver3.2307
オブジェクトaをオブジェクトbで初期化しても必ずオブジェクトaのメンバ変数とオブジェクトbのメンバ変数の独立性は保たれます
オブジェクトaをオブジェクトbで初期化しても必ずオブジェクトaのメンバ変数とオブジェクトbのメンバ変数の独立性は保たれます
つづきで~す
ソーラー「
SuutitoMoji a = b;
を実行したとき
クラスSuutitoMoji型のオブジェクトa
と
クラスSuutitoMoji型のオブジェクトb
の独立性は保たれる
つまり
クラスSuutitoMoji型のオブジェクトaに格納されているデータが変更されても
クラスSuutitoMoji型のオブジェクトbに格納されているデータは変更されないし
クラスSuutitoMoji型のオブジェクトbに格納されているデータが変更されても
クラスSuutitoMoji型のオブジェクトaに格納されているデータは変更されません」
マックス「それはそうだろう。普通過ぎるだろうぉぉ」
ソーラー「えへへ そう思いますか😊
私もそう思います
でも
私は
さんざん勘違いしていました( ^ω^)・・・
いやあ やっちまったなぁ~
さて
次のような
クラスSuutitoMojiがあるとします。
クラスSuutitoMojiのクラス宣言は次のようになっているとします」
👇
class SuutitoMoji{
public:
int x;
public:
char* i;
};
ソーラー「
もし
bのクラスSuutitoMoji型のオブジェクト宣言
SuutitoMoji b;
を実行したなら
クラスSuutitoMoji型のオブジェクトbのメンバ変数
b.x
b.i
が作製されますが
クラスSuutitoMoji型のオブジェクトbのメンバ変数
b.x
は
int型の変数
で
クラスSuutitoMoji型のオブジェクトbのメンバ変数
b.i
は
char*型のポインタ変数となっています
ということは
char*型のポインタ変数
b.i
は
char*型のポインタ変数なので
char型の変数のアドレスを格納することができます
ということは
new char[50];
を実行して動的に
連続したchar型の配列変数50個分のメモリ(50バイト分)を確保した場合
b.i=new char[50];
を実行することにより
連続したchar型の配列変数50個分のメモリ(50バイト分)の
先頭のメモリのアドレスを
char*型のポインタ変数であるオブジェクトbのメンバ変数
b.i
に格納することができます
このとき
strcpy関数(どの統合開発環境でもおつかいいただけます)
や
strcpy_s関数(Visual Studioをお使いの方のみおつかいいただけます)
を
用いて
b.i=new char[50];(動的にメモリを確保しています)
を実行して
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iに格納されることになったアドレス番号
のついたメモリを先頭とするメモリ領域に
文字列データを
格納してみたいと思います」
マックス「はぁ? strcpy関数? わっかりにくいぞ」
ソーラー「そっか・・・
では😊
もうちょっと簡潔にして
strcpy関数(どの統合開発環境でもおつかいいただけます)
や
strcpy_s関数(Visual Studioをお使いの方のみおつかいいただけます)
を
用いて
動的に確保したメモリに
文字列データを
格納してみたいと思います
で
どうかな?」
マックス「いいなあ これ、この説明なんだよ
て
strcpy関数ってなんのことだったか~忘れちまったぜぃ😊」
註)
Visual Studioをお使いの方は
strcpy関数をお使いになる場合は
プログラムの先頭に
#pragma warning(disable: 4996)
を記述してください
strcpy関数を用いれば
strcpy(b.i, "ねこねこ");
を実行して
文字列データ
"ねこねこ"
を
char*型のポインタ変数であるクラスSuutitoMoji型のオブジェクトbのメンバ変数
b.i
が格納しているアドレス番号の付いたメモリを先頭とする連続したメモリ領域に
格納することができます
つまり
文字列データ
"ねこねこ"
を
b.i=new char[50];
を実行して
動的に確保したメモリに格納することができます
Visual Studioをお使いの方は
プログラムの先頭に
#pragma warning(disable: 4996)
を記述しなくても
strcpy_s関数を用いて
strcpy_s(b.i, 50,"ねこねこ");
を実行して
文字列データ
"ねこねこ"
を
char*型のポインタ変数であるオブジェクトbのメンバ変数
b.i
が格納しているアドレス番号の付いたメモリに格納することができます
つまり
文字列データ
"ねこねこ"
を
b.i=new char[50];
を実行して
動的に確保したメモリに格納することができます
と💖こ💖ろ💖で💖😊
strcpy_s関数を用いる場合は
クラスSuutitoMoji型のオブジェクトbのメンバ変数
b.i
が格納しているアドレス番号を先頭とする動的に確保した連続したメモリ領域に
何バイト分までのデータを格納することができるかを指定する必要があります
そうですね
strcpy_s(b.i, 50,"ねこねこ");
のように
第2引数に50のように数値を記述する必要があります
この場合は
クラスSuutitoMoji型のオブジェクトbのメンバ変数
b.i
が格納しているアドレス番号を先頭とする連続した動的に確保したメモリ領域に
50バイト分までのデータを格納することができます
第2引数を記述せずに
strcpy_s(b.i, "ねこねこ");
を実行しようとすると
ビルドエラーが表示されます
では
文字列データ
"ねこねこ"
を
char*型のポインタ変数であるクラスSuutitoMoji型のオブジェクトbのメンバ変数
b.i
が格納しているアドレス番号を先頭とする連続した動的に確保したメモリ領域に
格納するプログラムを実行してみます
もっと簡単にいいかえてみます
strcpy_s関数は
あるメモリ領域に格納されている文字列データを
別のメモリ領域にコピーする機能があります
strcpy_s(b.i, 50,"ねこねこ");
(この場合 文字列データ"ねこねこ"はあるメモリ領域に格納されています)
を実行することにより
文字列データ
"ねこねこ"
を
(b.i = new char[50];
を実行して)
動的に確保したメモリに
(char*型のポインタ変数であるb.iには動的に確保したメモリ領域の先頭のメモリのアドレスが格納されています)
格納するプログラムを実行してみます
そのプログラムはこちらです
👇
#pragma warning(disable: 4996)
#include <iostream>
using namespace std;
class SuutitoMoji{
public:
int x;
public:
char* i;
};
int main() {
SuutitoMoji b;
b.x = 1;
b.i = new char[50];
strcpy(b.i, "ねこねこ");
cout << b.x << "\n";
cout << b.i << "\n";
return 0;
}
プログラムの実行結果
1
ねこねこ
Visual Studioをお使いの方はこちらのプログラムも実行できます
👇
#include <iostream>
using namespace std;
class SuutitoMoji{
public:
int x;
public:
char* i;
};
int main() {
SuutitoMoji b;
b.x = 1;
b.i = new char[50];
strcpy_s(b.i, 50, "ねこねこ");//strcpy_s関数をもちいています
cout << b.x << "\n";
cout << b.i << "\n";
return 0;
}
プログラムの実行結果
1
ねこねこ
ソーラー「
cout << b.i << "\n";
の実行により
コマンドプロンプト画面に
ねこねこ
が表示されています
b.i = new char[50];
によって
動的に確保したメモリに
文字列データ
"ねこねこ"
を格納することができました
strcpy_s(b.i, 50, "ねこねこ");
は
オブジェクトbのメンバ変数b.iが格納しているアドレス番号の付いたメモリを先頭とするメモリ領域に
文字列データを格納しているのですね」
マックス「ふむふむう いい説明だな・・・」
ソーラー「そうです? えへへ
ここで
SuutitoMoji b;
によって作製された
クラスSuutitoMoji型のオブジェクトbを用いて
aのオブジェクト宣言、初期化
SuutitoMoji a = b;
を実行してみたいと思います
その時のプログラムはこちらです
👇
#pragma warning(disable: 4996)
#include <iostream>
using namespace std;
class SuutitoMoji {
public:
int x;
public:
char* i;
};
int main() {
SuutitoMoji b;
b.x = 1;
b.i = new char[50];
strcpy(b.i, "ねこねこ");
SuutitoMoji a = b;
cout << b.x << "\n";
cout << b.i << "\n";
cout << a.x << "\n";
cout << a.i << "\n";
return 0;
}
プログラムの実行結果
1
ねこねこ
1
ねこねこ
Visual Studioをお使いの方はこちらも実行できます
👇
#include <iostream>
using namespace std;
class SuutitoMoji{
public:
int x;
public:
char* i;
};
int main() {
SuutitoMoji b;
b.x = 1;
b.i = new char[50];
strcpy_s(b.i, 50, "ねこねこ");
SuutitoMoji a = b;
cout << b.x << "\n";
cout << b.i << "\n";
cout << a.x << "\n";
cout << a.i << "\n";
return 0;
}
プログラムの実行結果
1
ねこねこ
1
ねこねこ
ソーラー「このプログラムの最大の注目ポイントは
strcpy_s(b.i, 50, "ねこねこ");
を実行した後
SuutitoMoji a = b;
の実行により
クラスSuutitoMoji型のオブジェクトaのメンバ変数
a.x
a.i
に
クラスSuutitoMoji型のオブジェクトbのメンバ変数
b.x
b.i
を代入することにより
クラスSuutitoMoji型のオブジェクトaのメンバ変数
a.x
には
数値データ1
が
クラスSuutitoMoji型のオブジェクトaのメンバ変数
a.i
には
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iが格納しているアドレス番号が
格納されているという点です
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iが格納しているアドレス番号が
付いたメモリを先頭とするメモリ領域には
文字列データ
"ねこねこ"
が格納されています
マックス「
文字列データ
"ねこねこ"
は
b.i = new char[50];
の実行により
動的に確保したメモリに格納されているんだろう
(このとき
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iには動的に確保したメモリ領域の先頭のメモリのアドレス番号が格納されています)
」
ソーラー「そうなんです
SuutitoMoji a = b;
の実行により
a.i=b.i;
が実行されることになります
b.i = new char[50];
の実行により
クラスSuutitoMoji型のオブジェクトbのメンバ変数
b.i
に格納された
動的に確保されたメモリ領域の
先頭のメモリのアドレスは
クラスSuutitoMoji型のオブジェクトaのメンバ変数
a.i
クラスSuutitoMoji型のオブジェクトbのメンバ変数
b.i
の両方に格納されていることになります
このとき
🌹クラスSuutitoMoji型のオブジェクトaのメンバ変数🌹
🌹a.i🌹
🌷クラスSuutitoMoji型のオブジェクトbのメンバ変数🌷
🌷b.i🌷
のどちらにstrcpy_s関数を作用させても
動的に確保したメモリに
文字列データを格納することができます
なぜなら
ポインタ変数であるオブジェクトaのメンバ変数a.iに格納されたアドレス
と
ポインタ変数であるオブジェクトbのメンバ変数b.iに格納されたアドレス
はともに
💖動的に確保したメモリの先頭のアドレス💖
を格納しており
strcpy(a.i, "ねこねこ");
strcpy(b.i, "ねこねこ");
が実行されると
ともに
動的に確保したメモリに
文字列データ"ねこねこ"は格納されることになるからです
そのことを示すプログラムはこちらです
👇
#pragma warning(disable: 4996)
#include <iostream>
using namespace std;
class SuutitoMoji{
public:
int x;
public:
char* i;
};
int main() {
SuutitoMoji b;
b.x = 1;
b.i = new char[50];
strcpy(b.i, "ねこねこ");
SuutitoMoji a = b;
cout << b.x << "\n";
cout << b.i << "\n";
cout << a.x << "\n";
cout << a.i << "\n";
a.x = 2;
strcpy(b.i, "ねこねこねこ");
cout << b.x << "\n";
cout << b.i << "\n";
cout << a.x << "\n";
cout << a.i << "\n";
a.x = 3;
strcpy(a.i, "ネコネコにゃんこ");
cout << b.x << "\n";
cout << b.i << "\n";
cout << a.x << "\n";
cout << a.i << "\n";
return 0;
}
プログラムの実行結果
1
ねこねこ
1
ねこねこ
1
ねこねこねこ
2
ねこねこねこ
1
ネコネコにゃんこ
3
ネコネコにゃんこ
Visual Studioをお使いの場合はこちらのプログラムも実行できます
👇
#include <iostream>
using namespace std;
class SuutitoMoji{
public:
int x;
public:
char* i;
};
int main() {
SuutitoMoji b;
b.x = 1;
b.i = new char[50];
strcpy_s(b.i, 50, "ねこねこ");
SuutitoMoji a = b;
cout << b.x << "\n";
cout << b.i << "\n";
cout << a.x << "\n";
cout << a.i << "\n";
a.x = 2;
strcpy_s(b.i, 50, "ねこねこねこ");
cout << b.x << "\n";
cout << b.i << "\n";
cout << a.x << "\n";
cout << a.i << "\n";
a.x = 3;
strcpy_s(a.i, 50, "ネコネコにゃんこ");
cout << b.x << "\n";
cout << b.i << "\n";
cout << a.x << "\n";
cout << a.i << "\n";
return 0;
}
プログラムの実行結果
1
ねこねこ
1
ねこねこ
1
ねこねこねこ
2
ねこねこねこ
1
ネコネコにゃんこ
3
ネコネコにゃんこ
ソーラー「
このプログラムでは
まず
SuutitoMoji b;
b.x = 1;
b.i = new char[50];
strcpy_s(b.i, 50, "ねこねこ");
の実行により
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.xには
数値データ1
が
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iには
文字列データ
"ねこねこ"
を格納しているメモリの先頭のアドレスが格納されます
そして
SuutitoMoji a = b;
が実行されると
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.x
には
数値データ1
が
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.iには
文字列データ
"ねこねこ"
を格納している動的に確保したメモリ領域の先頭のメモリのアドレスが格納されます
もちろん
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.xには
数値データ1
が
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iには
文字列データ
"ねこねこ"
を格納している動的に確保したメモリ領域の先頭のメモリのアドレスが
保存されたままですね
さあいよいよです
このプログラムの
a.x = 2;
strcpy_s(b.i, 50, "ねこねこねこ");
に御注目ください
a.x = 2;
が実行されると
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.xに格納されている数値データは
1から2に変化しますが
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.xに格納されている数値データは
1のまま変化しないことが
後に続く命令文
cout << b.x << "\n";
cout << b.i << "\n";
cout << a.x << "\n";
cout << a.i << "\n";
の実行結果が
1
ねこねこねこ
2
ねこねこねこ
となっていることからわかります
マックス「そんなの あたりまえなのでないか?」
ソーラー「ふふっ
そうなんです
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.x
と
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.x
は
それぞれ独立したメモリを管理しているからなんです
さて
b.iには動的に確保したメモリ領域の先頭のメモリのアドレスが格納されています
次は
動的に確保したメモリ領域に
新たに
文字列データ
"ねこねこねこ"
を
つまり
b.iを用いて動的に確保したメモリに
文字列データ
"ねこねこねこ"
を格納する命令文
strcpy_s(b.i, 50, "ねこねこねこ");
が実行されていますね
その解説です
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iが格納しているアドレス番号の付いたメモリを先頭とするメモリ領域に
格納されている文字列データは
"ねこねこ"
から
"ねこねこねこ"
に変化しますが
つまり
動的に確保されているメモリに格納されている文字列データは
"ねこねこ"
から
"ねこねこねこ"
に変化しますが
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.iが格納しているアドレス番号の付いたメモリを先頭とするメモリ領域に
格納されている文字列データも
"ねこねこ"
から
"ねこねこねこ"
に変化します
そのことが
後に続く命令文
cout << b.x << "\n";
cout << b.i << "\n";
cout << a.x << "\n";
cout << a.i << "\n";
の実行結果が
1
ねこねこねこ
2
ねこねこねこ
となっていることからわかります
なぜなら
SuutitoMoji a = b;
の実行により
a.i=b.i
が実行されているので
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.iが格納しているアドレス番号
と
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iが格納しているアドレス番号は
同じアドレス番号になっているからです
まさに
a.i=b.i
というわけです
ですので
b.iを用いて
strcpy_s(b.i, 50, "ねこねこねこ");
を実行して
オブジェクトbのメンバ変数b.iが格納しているアドレス番号の付いたメモリを先頭とするメモリ領域に
文字列データ"ねこねこねこ"
を格納するということは
a.iを用いて
strcpy_s(a.i, 50, "ねこねこねこ");
を実行して
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.iが格納しているアドレス番号の付いたメモリを先頭とするメモリ領域に
文字列データ"ねこねこねこ"
を格納することと等しいというわけです
strcpy_s(a.i, 50, "ねこねこねこ");
もしくは
strcpy_s(b.i, 50, "ねこねこねこ");
のどちらを実行しても
同じメモリ領域に
文字列データ"ねこねこねこ"は格納されることになるのですね
もちろん
そのメモリ領域の先頭のメモリのアドレスは
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.iに格納されていますし
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iにも格納されています
今のプログラムの
cout << b.x << "\n";
cout << b.i << "\n";
cout << a.x << "\n";
cout << a.i << "\n";
の実行結果が
1
ねこねこねこ
2
ねこねこねこ
になっています
この
cout << b.x << "\n";
cout << b.i << "\n";
cout << a.x << "\n";
cout << a.i << "\n";
の中の
cout << b.i << "\n";
と
cout << a.i << "\n";
の実行結果に御注目下さい
命令文
cout << b.i << "\n";
は
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iに格納されているアドレス番号の付いたメモリを先頭とするメモリ領域に
格納されている文字列データを表示する命令文であり
cout << a.i << "\n";
は
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.iに格納されているアドレス番号の付いたメモリを先頭とするメモリ領域に
格納されている文字列データを表示する命令文ですね
そして
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iに格納されているアドレス番号
と
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.iに格納されているアドレス番号
は等しいので
cout << b.i << "\n";
と
cout << a.i << "\n";
の実行結果は
ともに
ねこねこねこ
がコマンドプロンプト画面に表示されるというわけです
もちろん
この場合でも
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.i
と
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.i
は独立している
つまり
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.i
と
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.i
は
それぞれ別のメモリを管理しています
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.i
と
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.i
はそれぞれ別のメモリを管理していますが
それぞれに
同じアドレス番号が格納されているというわけです」
マックス「そっか
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.i
と
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.i
はそれぞれ別のメモリを管理している・・・が
同じアドレスが格納されている・・・
」
ソーラー「そうなんです
strcpy(b.i, "ねこねこねこ");
が実行されると
cout << b.i << "\n";
と
cout << a.i << "\n";
の実行結果は
ともに
ねこねこねこ
になるので
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.i
と
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.i
は
(^_^)v同じメモリを管理しているのでは?(#^^#)
と思われる方もおられるかもしれませんが
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.i
と
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.i
の独立性は保たれています
つまり
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.i
と
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.i
の管理しているメモリは異なっています
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.i
と
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.i
の管理しているメモリに同じアドレスが代入されているだけです
だから
cout << b.i << "\n";
と
cout << a.i << "\n";
の実行結果は
ともに
ねこねこねこ
になるのです」
マックス「
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.i
と
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.i
の独立性は保たれている・・・か・・・
まあそ~だよな」
ソーラー「
さらに次に続く命令文
a.x = 3;
strcpy_s(a.i, 50, "ネコネコにゃんこ");
に御注目下さい
a.x = 3;
が実行されると
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.xに格納されている数値データは
2から3に変化しますが
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.xに格納されている数値データは
1のまま変化しないことが
次に続く命令文
cout << b.x << "\n";
cout << b.i << "\n";
cout << a.x << "\n";
cout << a.i << "\n";
の実行結果が
1
ネコネコにゃんこ
3
ネコネコにゃんこ
となっていることからわかります
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.x
と
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.x
は
それぞれ独立したメモリを管理しているからですね
そして
今度は
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.iの格納しているアドレス番号のついたメモリを先頭とするメモリ領域に
文字列データ
"ネコネコにゃんこ"
を格納する命令文
strcpy_s(a.i, 50, "ネコネコにゃんこ");
が実行ですね
strcpy_s(a.i, 50, "ネコネコにゃんこ");
が実行されると
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.iの格納しているアドレス番号のついたメモリを先頭とするメモリ領域に
格納される文字列データは
"ねこねこねこ"
から
"ネコネコにゃんこ”
に変化しますが
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iの格納しているアドレス番号のついたメモリを先頭とするメモリ領域に
格納される文字列データも
"ねこねこねこ"
から
"ネコネコにゃんこ”
に変化することになります
なぜなら
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.iに格納されているアドレス
と
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iに格納されているアドレス
は
💖同じアドレス💖
であり
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.iの格納しているアドレス番号のついたメモリを先頭とするメモリ領域
と
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iの格納しているアドレス番号のついたメモリを先頭とするメモリ領域
は
同一のメモリ領域だからです
そのことが
後に続く命令文
cout << b.x << "\n";
cout << b.i << "\n";
cout << a.x << "\n";
cout << a.i << "\n";
の実行結果が
1
ネコネコにゃんこ
3
ネコネコにゃんこ
となっていることからわかります
もちろん
この場合も
オブジェクトaのメンバ変数a.i
と
オブジェクトbのメンバ変数b.i
は独立しています」
マックス「なんか 不思議な感じがするな・・・」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます