Cắt đối tượng là gì?

766
Frankomania 2008-11-09 01:10.

Ai đó đã đề cập đến nó trong IRC như là vấn đề cắt.

15 answers

635
David Dibben 2008-11-09 01:22.

"Slicing" là nơi bạn gán một đối tượng của lớp dẫn xuất cho một thể hiện của lớp cơ sở, do đó làm mất một phần thông tin - một số thông tin bị "cắt" đi.

Ví dụ,

class A {
   int foo;
};

class B : public A {
   int bar;
};

Vì vậy, một đối tượng kiểu Bcó hai thành viên dữ liệu, foobar.

Sau đó, nếu bạn viết điều này:

B b;

A a = b;

Sau đó, thông tin bvề thành viên barbị mất trong a.

530
fgp 2013-01-23 05:00.

Hầu hết các câu trả lời ở đây không giải thích được vấn đề thực sự với việc cắt lát là gì. Họ chỉ giải thích những trường hợp lành tính của vết cắt chứ không phải những trường hợp nguy hiểm. Giả sử, giống như các câu trả lời khác, rằng bạn đang xử lý hai lớp AB, Bnguồn gốc (công khai) từ đâu A.

Trong trường hợp này, C ++ cho phép bạn chuyển một thể hiện của toán tử gán Bcho A'(và cả phương thức tạo bản sao). Điều này hoạt động vì một thể hiện của Bcó thể được chuyển đổi thành a const A&, đó là điều mà các toán tử gán và các hàm tạo bản sao mong đợi các đối số của chúng.

Trường hợp lành tính

B b;
A a = b;

Không có gì xấu xảy ra ở đó - bạn đã yêu cầu Amột bản sao của nó B, và đó chính xác là những gì bạn nhận được. Chắc chắn, asẽ không chứa một số bthành viên, nhưng làm thế nào để nó? Rốt cuộc là Akhông phải a B, cho nên nó còn chưa nghe nói về những thành viên này, huống chi là có thể lưu trữ bọn họ.

Vụ án nguy hiểm

B b1;
B b2;
A& a_ref = b2;
a_ref = b1;
//b2 now contains a mixture of b1 and b2!

Bạn có thể nghĩ rằng đó b2sẽ là một bản sao của b1sau này. Nhưng, than ôi, không phải vậy! Nếu bạn kiểm tra nó, bạn sẽ phát hiện ra đó b2là một sinh vật Frankensteinian, được tạo ra từ một số khối b1(những khối Bkế thừa từ A), và một số khối b2(những khối chỉ Bchứa). Ôi chao!

Chuyện gì đã xảy ra? Chà, theo mặc định, C ++ không coi các toán tử gán là virtual. Do đó, dòng a_ref = b1sẽ gọi toán tử gán của A, không phải của B. Điều này là do, đối với các hàm không ảo, kiểu được khai báo (chính thức: tĩnh ) (là A&) xác định hàm nào được gọi, trái ngược với kiểu thực (chính thức: động ) (sẽ là B, vì a_reftham chiếu đến một phiên bản của B) . Bây giờ, Atoán tử gán của rõ ràng chỉ biết về các thành viên được khai báo A, vì vậy nó sẽ chỉ sao chép những thành viên đó, giữ nguyên các thành viên được thêm vào Bkhông thay đổi.

Một giải pháp

Chỉ gán cho các phần của một đối tượng thường không có ý nghĩa gì, nhưng thật không may, C ++ không cung cấp cách tích hợp nào để cấm điều này. Tuy nhiên, bạn có thể tự cuộn. Bước đầu tiên là làm cho toán tử gán ảo . Điều này sẽ đảm bảo rằng nó luôn là toán tử gán của kiểu thực tế được gọi, không phải của kiểu đã khai báo . Bước thứ hai là sử dụng dynamic_castđể xác minh rằng đối tượng được chỉ định có kiểu tương thích. Bước thứ ba là thực hiện nhiệm vụ thực sự trong một thành viên (được bảo vệ!) assign(), Vì B's assign()có thể sẽ muốn sử dụng Acác thành viên' s assign()để sao chép A'.

class A {
public:
  virtual A& operator= (const A& a) {
    assign(a);
    return *this;
  }

protected:
  void assign(const A& a) {
    // copy members of A from a to this
  }
};

class B : public A {
public:
  virtual B& operator= (const A& a) {
    if (const B* b = dynamic_cast<const B*>(&a))
      assign(*b);
    else
      throw bad_assignment();
    return *this;
  }

protected:
  void assign(const B& b) {
    A::assign(b); // Let A's assign() copy members of A from b to this
    // copy members of B from b to this
  }
};

Lưu ý rằng, để thuận tiện trong sạch, Boperator=covariantly đè kiểu trả về, vì nó biết rằng nó đang trở về một thể hiện của B.

158
Black 2008-11-09 01:28.

Nếu Bạn có một lớp cơ sở Avà một lớp dẫn xuất B, thì Bạn có thể làm như sau.

void wantAnA(A myA)
{
   // work with myA
}

B derived;
// work with the object "derived"
wantAnA(derived);

Bây giờ phương thức wantAnAcần một bản sao của derived. Tuy nhiên, đối tượng derivedkhông thể được sao chép hoàn toàn, vì lớp Bcó thể phát minh ra các biến thành viên bổ sung không có trong lớp cơ sở của nó A.

Do đó, để gọi wantAnA, trình biên dịch sẽ "cắt bỏ" tất cả các thành viên bổ sung của lớp dẫn xuất. Kết quả có thể là một đối tượng bạn không muốn tạo, bởi vì

  • nó có thể không đầy đủ,
  • nó hoạt động giống như một A-object (tất cả các hành vi đặc biệt của lớp Bđều bị mất).
42
geh 2014-08-23 08:33.

Đây là tất cả các câu trả lời tốt. Tôi chỉ muốn thêm một ví dụ thực thi khi chuyển các đối tượng theo giá trị so với tham chiếu:

#include <iostream>

using namespace std;

// Base class
class A {
public:
    A() {}
    A(const A& a) {
        cout << "'A' copy constructor" << endl;
    }
    virtual void run() const { cout << "I am an 'A'" << endl; }
};

// Derived class
class B: public A {
public:
    B():A() {}
    B(const B& a):A(a) {
        cout << "'B' copy constructor" << endl;
    }
    virtual void run() const { cout << "I am a 'B'" << endl; }
};

void g(const A & a) {
    a.run();
}

void h(const A a) {
    a.run();
}

int main() {
    cout << "Call by reference" << endl;
    g(B());
    cout << endl << "Call by copy" << endl;
    h(B());
}

Đầu ra là:

Call by reference
I am a 'B'

Call by copy
'A' copy constructor
I am an 'A'
30
The Archetypal Paul 2008-11-09 01:14.

Kết quả phù hợp thứ ba trên google cho "C ++ cắt" mang lại cho tôi bài viết trên Wikipedia này http://en.wikipedia.org/wiki/Object_slicing và điều này (nóng, nhưng một số bài viết đầu tiên xác định vấn đề): http://bytes.com/forum/thread163565.html

Vì vậy, đó là khi bạn gán một đối tượng của một lớp con cho lớp siêu. Lớp cha không biết gì về thông tin bổ sung trong lớp con và không có chỗ để lưu trữ nó, vì vậy thông tin bổ sung bị "cắt nhỏ".

Nếu những liên kết đó không cung cấp đủ thông tin cho một "câu trả lời hay", vui lòng chỉnh sửa câu hỏi của bạn để cho chúng tôi biết bạn đang tìm kiếm thêm thông tin gì.

29
Walter Bright 2008-11-09 01:56.

Vấn đề cắt là nghiêm trọng vì nó có thể dẫn đến hỏng bộ nhớ và rất khó để đảm bảo một chương trình không bị như vậy. Để thiết kế nó ra khỏi ngôn ngữ, các lớp hỗ trợ kế thừa chỉ được truy cập bằng tham chiếu (không phải theo giá trị). Ngôn ngữ lập trình D có thuộc tính này.

Hãy xem xét lớp A và lớp B bắt nguồn từ A. Sự hỏng bộ nhớ có thể xảy ra nếu phần A có một con trỏ p và một cá thể B trỏ p tới dữ liệu bổ sung của B. Sau đó, khi dữ liệu bổ sung bị loại bỏ, p sẽ trỏ đến rác.

11
Kartik Maheshwari 2018-03-07 23:35.

Trong C ++, một đối tượng lớp dẫn xuất có thể được gán cho một đối tượng lớp cơ sở, nhưng cách khác là không thể.

class Base { int x, y; };

class Derived : public Base { int z, w; };

int main() 
{
    Derived d;
    Base b = d; // Object Slicing,  z and w of d are sliced off
}

Việc cắt đối tượng xảy ra khi một đối tượng lớp dẫn xuất được gán cho một đối tượng lớp cơ sở, các thuộc tính bổ sung của một đối tượng lớp dẫn xuất được cắt ra để tạo thành đối tượng lớp cơ sở.

7
Steve Steiner 2008-11-09 07:38.

Vì vậy ... Tại sao mất thông tin có nguồn gốc là xấu? ... bởi vì tác giả của lớp dẫn xuất có thể đã thay đổi cách biểu diễn sao cho việc cắt bỏ thông tin bổ sung sẽ làm thay đổi giá trị được biểu diễn bởi đối tượng. Điều này có thể xảy ra nếu lớp dẫn xuất nếu được sử dụng để lưu vào bộ nhớ cache một biểu diễn hiệu quả hơn cho các hoạt động nhất định, nhưng tốn kém để chuyển đổi trở lại biểu diễn cơ sở.

Cũng nghĩ rằng ai đó cũng nên đề cập đến những gì bạn nên làm để tránh bị cắt ... Nhận một bản sao Tiêu chuẩn mã hóa C ++, 101 hướng dẫn quy tắc và các phương pháp hay nhất. Xử lý cắt lát là # 54.

Nó gợi ý một mô hình hơi phức tạp để giải quyết hoàn toàn vấn đề: có một hàm tạo bản sao được bảo vệ, một DoClone ảo thuần túy được bảo vệ và một Bản sao công khai với một xác nhận sẽ cho bạn biết nếu một lớp dẫn xuất (xa hơn) không triển khai DoClone một cách chính xác. (Phương thức Clone tạo một bản sao sâu thích hợp của đối tượng đa hình.)

Bạn cũng có thể đánh dấu hàm tạo bản sao trên cơ sở rõ ràng cho phép cắt rõ ràng nếu muốn.

7
ididak 2008-11-09 14:31.

Vấn đề cắt trong C ++ phát sinh từ ngữ nghĩa giá trị của các đối tượng của nó, chủ yếu vẫn là do khả năng tương thích với cấu trúc C. Bạn cần sử dụng tham chiếu rõ ràng hoặc cú pháp con trỏ để đạt được hành vi đối tượng "bình thường" được tìm thấy trong hầu hết các ngôn ngữ khác làm đối tượng, tức là, các đối tượng luôn được truyền xung quanh bằng tham chiếu.

Câu trả lời ngắn gọn là bạn cắt đối tượng bằng cách gán đối tượng dẫn xuất cho đối tượng cơ sở theo giá trị , tức là đối tượng còn lại chỉ là một phần của đối tượng dẫn xuất. Để duy trì ngữ nghĩa giá trị, cắt là một hành vi hợp lý và có cách sử dụng tương đối hiếm, không tồn tại trong hầu hết các ngôn ngữ khác. Một số người coi nó là một tính năng của C ++, trong khi nhiều người coi nó là một trong những điểm kỳ quặc / sai lầm của C ++.

6
haberdar 2012-01-29 08:00.

1. ĐỊNH NGHĨA CỦA VẤN ĐỀ SLICING

Nếu D là một lớp dẫn xuất của lớp cơ sở B, thì bạn có thể gán một đối tượng kiểu Bắt nguồn cho một biến (hoặc tham số) kiểu Cơ sở.

THÍ DỤ

class Pet
{
 public:
    string name;
};
class Dog : public Pet
{
public:
    string breed;
};

int main()
{   
    Dog dog;
    Pet pet;

    dog.name = "Tommy";
    dog.breed = "Kangal Dog";
    pet = dog;
    cout << pet.breed; //ERROR

Mặc dù phép gán ở trên được phép, nhưng giá trị được gán cho biến vật nuôi sẽ làm mất trường giống của nó. Đây được gọi là vấn đề cắt lát .

2. CÁCH KHẮC PHỤC VẤN ĐỀ SLICING

Để giải quyết vấn đề, chúng tôi sử dụng con trỏ đến các biến động.

THÍ DỤ

Pet *ptrP;
Dog *ptrD;
ptrD = new Dog;         
ptrD->name = "Tommy";
ptrD->breed = "Kangal Dog";
ptrP = ptrD;
cout << ((Dog *)ptrP)->breed; 

Trong trường hợp này, không có thành viên dữ liệu hoặc hàm thành viên nào của biến động được ptrD (đối tượng lớp con cháu) trỏ tới sẽ bị mất. Ngoài ra, nếu bạn cần sử dụng các hàm thì hàm phải là hàm ảo.

4
Minok 2009-07-25 09:45.

Đối với tôi, việc cắt lớp không phải là vấn đề quá lớn ngoài việc các lớp và chương trình của riêng bạn được kiến ​​trúc / thiết kế kém.

Nếu tôi truyền một đối tượng lớp con vào dưới dạng tham số cho một phương thức, phương thức này nhận một tham số kiểu siêu lớp, tôi chắc chắn nên biết điều đó và biết bên trong, phương thức được gọi sẽ chỉ hoạt động với đối tượng lớp cha (hay còn gọi là baseclass).

Đối với tôi, dường như chỉ có kỳ vọng không hợp lý rằng việc cung cấp một lớp con mà một lớp cơ sở được yêu cầu, bằng cách nào đó sẽ dẫn đến kết quả cụ thể của lớp con, sẽ gây ra vấn đề cắt lát. Thiết kế kém của nó trong việc sử dụng phương pháp hoặc triển khai lớp con kém. Tôi đoán nó thường là kết quả của việc hy sinh thiết kế OOP tốt để có lợi cho hiệu suất hoặc hiệu suất.

3
Dude 2012-10-18 17:22.

Được rồi, tôi sẽ thử sau khi đọc nhiều bài đăng giải thích việc cắt đối tượng nhưng không phải cách nó trở nên có vấn đề.

Tình huống xấu có thể dẫn đến hỏng bộ nhớ như sau:

  • Lớp cung cấp (vô tình, có thể do trình biên dịch tạo ra) trên một lớp cơ sở đa hình.
  • Máy khách sao chép và cắt một thể hiện của một lớp dẫn xuất.
  • Máy khách gọi một chức năng thành viên ảo truy cập trạng thái cắt nhỏ.
3
Santosh 2014-03-13 08:08.

Cắt nghĩa là dữ liệu được thêm vào bởi một lớp con sẽ bị loại bỏ khi một đối tượng của lớp con được truyền hoặc trả về bởi giá trị hoặc từ một hàm mong đợi một đối tượng lớp cơ sở.

Giải thích: Hãy xem xét khai báo lớp sau:

           class baseclass
          {
                 ...
                 baseclass & operator =(const baseclass&);
                 baseclass(const baseclass&);
          }
          void function( )
          {
                baseclass obj1=m;
                obj1=m;
          }

Vì các hàm sao chép của baseclass không biết bất cứ điều gì về phần dẫn xuất chỉ có phần cơ sở của phần dẫn xuất được sao chép. Điều này thường được gọi là cắt lát.

1
quidkid 2012-11-30 02:32.
class A 
{ 
    int x; 
};  

class B 
{ 
    B( ) : x(1), c('a') { } 
    int x; 
    char c; 
};  

int main( ) 
{ 
    A a; 
    B b; 
    a = b;     // b.c == 'a' is "sliced" off
    return 0; 
}
1
Sorush 2020-09-13 01:27.

Tôi thấy tất cả các câu trả lời đề cập đến việc cắt đối tượng xảy ra khi các thành viên dữ liệu được cắt. Ở đây tôi đưa ra một ví dụ rằng các phương thức không bị ghi đè:

class A{
public:
    virtual void Say(){
        std::cout<<"I am A"<<std::endl;
    }
};

class B: public A{
public:
    void Say() override{
        std::cout<<"I am B"<<std::endl;
    }
};

int main(){
   B b;
   A a1;
   A a2=b;

   b.Say(); // I am B
   a1.Say(); // I am A
   a2.Say(); // I am A   why???
}

B (đối tượng b) có nguồn gốc từ A (đối tượng a1 và a2). b và a1, như chúng ta mong đợi, gọi hàm thành viên của chúng. Nhưng từ quan điểm đa hình, chúng ta không mong đợi a2, được gán bởi b, không bị ghi đè. Về cơ bản, a2 chỉ lưu một phần lớp A của b và đó là việc cắt đối tượng trong C ++.

Để giải quyết vấn đề này, nên sử dụng tham chiếu hoặc con trỏ

 A& a2=b;
 a2.Say(); // I am B

hoặc là

A* a2 = &b;
a2->Say(); // I am B

Để biết thêm chi tiết, hãy xem bài đăng của tôi

Related questions

MORE COOL STUFF

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett đã bất chấp những lời khuyên hẹn hò điển hình khi cô gặp chồng mình.

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Michael Sheen là một diễn viên phi lợi nhuận nhưng chính xác thì điều đó có nghĩa là gì?

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Ngôi sao của Hallmark Colin Egglesfield chia sẻ về những cuộc gặp gỡ với người hâm mộ ly kỳ tại RomaDrama Live! cộng với chương trình INSPIRE của anh ấy tại đại hội.

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Bạn sẽ phải phủi sạch đầu đĩa Blu-ray hoặc DVD để xem tại sao Northern Exposure trở thành một trong những chương trình nổi tiếng nhất của thập niên 90.

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

8 công dụng tuyệt vời của Baking Soda và Giấm

8 công dụng tuyệt vời của Baking Soda và Giấm

Bạn biết đấy, hai sản phẩm này là nguồn điện để làm sạch, riêng chúng. Nhưng cùng với nhau, chúng có một loạt công dụng hoàn toàn khác.

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Thủy điện rất cần thiết cho lưới điện của Hoa Kỳ, nhưng nó chỉ tạo ra năng lượng khi có nước di chuyển. Bao nhiêu nhà máy thủy điện có thể gặp nguy hiểm khi các hồ và sông cạn kiệt?

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Tóc tỉa từ các tiệm và các khoản quyên góp cá nhân có thể được tái sử dụng như những tấm thảm thấm dầu và giúp bảo vệ môi trường.

BoJack Horseman vẫn gan ruột và gan dạ hơn bao giờ hết trong phần 3

BoJack Horseman vẫn gan ruột và gan dạ hơn bao giờ hết trong phần 3

BoJack Horseman (Ảnh: Netflix) BoJack Horseman bắt đầu mùa thứ ba với sự xuất hiện của nhân vật tiêu biểu, người vẫn đang theo đuổi những lời khen ngợi từ giới phê bình trong một nỗ lực tuyệt vọng để tìm ra ý nghĩa trong cuộc sống của mình. Mùa thứ hai về số phận bi kịch của Raphael Bob-Waksberg dày đặc những trò đùa cũng như tuyệt vọng.

Xem cách tính năng lái tự động cập nhật của Tesla bùng phát như thế nào khi bạn bỏ qua các cảnh báo của nó

Xem cách tính năng lái tự động cập nhật của Tesla bùng phát như thế nào khi bạn bỏ qua các cảnh báo của nó

Bản nâng cấp Phiên bản 8.0 gần đây của Tesla đối với hệ thống Lái xe tự động được thiết kế để cải thiện hệ thống và mối quan hệ của nó với người lái.

UnREAL, Chương trình Truyền hình Về Truyền hình Thực tế Chúng tôi Không biết Chúng tôi Cần

UnREAL, Chương trình Truyền hình Về Truyền hình Thực tế Chúng tôi Không biết Chúng tôi Cần

Chắc chắn khi con cái chúng ta xem lại các chương trình chúng ta đã xem vào khoảng năm 2015, chúng sẽ thấy UnREAL, một chương trình truyền hình mới chiếu vào tối Thứ Hai của Lifetime — bạn sẽ thấy đúng lúc, sẽ phát sóng ngay sau khi The Bachelor kết thúc — như một chương trình không thể được thực hiện vào bất kỳ thời điểm nào khác trong lịch sử truyền hình, nhưng một chương trình cảm thấy cần thiết để xem bây giờ. UnREAL có sự tham gia của Shiri Appleby trong vai Rachel, một nhà sản xuất truyền hình cho một chương trình về cơ bản là The Bachelor, mặc dù trong thế giới này, nó được gọi là Vĩnh viễn.

Sau tất cả, Josh Trank sẽ không đạo diễn bộ phim tuyển tập Star Wars thứ hai

Sau tất cả, Josh Trank sẽ không đạo diễn bộ phim tuyển tập Star Wars thứ hai

Thông báo chính thức đến trực tiếp từ trang web của Star Wars: Fantastic Four, đạo diễn Josh Trank, một người bí ẩn không xuất hiện tại đại hội Star Wars Celebration gần đây, sẽ không chỉ đạo phần hai Star Wars Anthology. Đây là tuyên bố được đăng ngày hôm qua: Tất cả thực sự là ngôn ngữ rất lịch sự, nhưng một bài báo của Hollywood Reporter cho thấy tất cả đều không tốt ở hậu trường, gọi sự ra đi là "một vụ sa thải" một phần dựa trên "hành vi bất thường" của Trank trong khi quay Fantastic Four: The Bài báo trích dẫn các nguồn gọi là Trank “đôi khi thiếu quyết đoán và thiếu sáng tạo,” và lưu ý rằng Fantastic Four, khởi chiếu vào ngày 7 tháng 8, đã được khởi động lại vào cuối tháng 4.

Edwin McCain ra mắt Grand Ole Opry: Quay cảnh hậu trường với nhạc sĩ 'I'll Be'

Edwin McCain ra mắt Grand Ole Opry: Quay cảnh hậu trường với nhạc sĩ 'I'll Be'

McCain, người đang làm việc cho một album mới, lần đầu tiên bước vào vòng kết nối vào tối thứ Sáu ở Nashville

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Rothschild's luggage got lost, but luckily she has an incredible closet to shop: Sister Paris Hilton's!

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa. Từ Hollywood đến New York và mọi nơi ở giữa, hãy xem các ngôi sao yêu thích của bạn đang làm gì!

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

Các nhà điều tra đang xem xét liệu nhóm và nghi phạm có biết nhau trước vụ tấn công hay không

Tôi viết như thế nào

Tôi viết như thế nào

Đối với tôi, mọi thứ là về dòng đầu tiên đó và nó sẽ đưa bạn đến đâu. Một số nhà văn bị điều khiển bởi cốt truyện, sự sắp xếp tinh tế của các quân cờ, trong khi những người khác bị lôi cuốn bởi một nhân vật và khả năng thực hiện một cuộc hành trình với một người bạn hư cấu mới.

Đường băng hạ cánh

Đường băng hạ cánh

Cuối hè đầu thu là mùa hoài niệm. Những chiếc đèn đường chiếu ánh sáng của chúng qua những con đường đẫm mưa, và những chiếc lá dưới chân - màu đỏ cam tắt trong bóng chạng vạng - là lời nhắc nhở về những ngày đã qua.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Vào năm 2021, tôi khuyến khích bạn suy nghĩ lại mọi thứ bạn biết về khách hàng mà bạn phục vụ và những câu chuyện bạn kể cho họ. Lùi lại.

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Vào ngày sinh nhật thứ 9 của Felix The Cat, tôi nhớ về một trong những mất mát lớn nhất trong cuộc đời trưởng thành của tôi - Sophie của tôi vào năm 2013. Tôi đã viết bài luận này và chia sẻ nó trên nền tảng này một thời gian ngắn vào năm 2013.

Language